我认为我对控制流程的理解是有缺陷的。我想要的是刮掉一堆URL,当我遇到它们时,从池中启动连接以将URL插入我的数据库。
我认为这里的问题是我对收益率的理解。如何使tormysql接受参数并异步使用连接将该参数写入数据库?
基本上,我只是希望insert_to_db()以异步方式将URL插入到我的数据库中。但是insert_to_db()实际上并没有运行。
from lxml import html
import tormysql
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import WebDriverException
import time
import sys
import csv
from shutil import copyfile
import requests
from bs4 import BeautifulSoup
pool = tormysql.ConnectionPool(
max_connections = 20, #max open connections
idle_seconds = 7200, #conntion idle timeout time, 0 is not timeout
wait_connection_timeout = 3, #wait connection timeout
host = "unidb.cfavdkskfrrc.us-west-2.rds.amazonaws.com",
user = "#",
passwd = "#",
db = "diplomacy_data",
charset = "utf8"
)
def insert_to_db(game_url):
print(game_url)
with (yield pool.Connection()) as conn:
try:
with conn.cursor() as cursor:
yield cursor.execute("INSERT INTO FvA_urls(URL) VALUES('%s')" % game_url)
except:
yield conn.rollback()
else:
print('committed', game_url)
yield conn.commit()
username = "#"
password = "#"
login_url = "https://webdiplomacy.net/logon.php"
driver = webdriver.Chrome()
driver.get(login_url)
driver.find_element_by_css_selector('body > div.content.content-follow-on > form > ul > li:nth-child(2) > input[type="text"]').send_keys(username)
driver.find_element_by_css_selector('body > div.content.content-follow-on > form > ul > li:nth-child(5) > input[type="password"]').send_keys(password)
driver.find_element_by_css_selector('body > div.content.content-follow-on > form > ul > li:nth-child(10) > input').click()
url = "https://webdiplomacy.net/gamelistings.php?"
params = "page-games=1&gamelistType=Finished&searchOn=on"
driver.get(url + params)
driver.find_element_by_css_selector('body > div:nth-child(5) > div:nth-child(2) > form > li:nth-child(5) > input[type="radio"]:nth-child(6)').click()
driver.find_element_by_css_selector('body > div:nth-child(5) > div:nth-child(2) > form > input').click()
# Get all the URLS
page_num = 0
while True:
page_num += 1
if page_num % 20 == 0:
print(page_num)
a = driver.find_elements(By.XPATH, '/html/body/div[5]/div[3]/div[*]/div[6]/div[2]/a')
if len(a) < 1:
pool.close()
exit()
else:
for button in a:
game_url = button.get_attribute('href')
insert_to_db(game_url)
driver.find_element_by_css_selector('body > div:nth-child(6) > div:nth-child(4) > div:nth-child(1) > div:nth-child(2) > a:nth-child(3) > img').click()
我可以在任何地方找到的TorMySQL用法的所有示例都只是对表的重复异步插入1。显然完全无用。
让每个连接独立完成某些事情是不可能的?就像这个库专门用于多次异步执行完全相同的事情一样吗?
答案 0 :(得分:0)
我认为字符串插值的'%'语法是一种被证明易受SQL注入攻击的模式。必须正确转义包含在SQL文本中的任何可能不安全的值。
我还认为包含单引号会导致生成无效的SQL语法,并且语句的执行失败并出现语法错误
cursor.execute("INSERT INTO FvA_urls(URL) VALUES('%s')" % game_url)
^ ^ ^
(我可能正在咆哮错误的树。我没有通过测试验证这一点。也许单引号是必需的或可以容忍的,也许这个值正在被正确转义。)
我认为更好的模式是使用逗号代替百分号,并将元组作为参数传递,如下所示:
cursor.execute("INSERT INTO FvA_urls(URL) VALUES( %s )", (game_url,))
^ ^ ^ ^ ^^
为了进行比较,请查看example/pool.py
cur = yield POOL.execute("SELECT SLEEP(%s)", (t,))
^ ^ ^^
我打赌这就是问题所在。
但是在StackOverflow作为问答网站的精神中,我认识到这些问题也被提出来了:
问:是否不可能让每个连接独立完成某些事情?问:就像这个库专门用于多次异步完成相同的事情一样吗?
example / pool.py中的代码是否回答了您的问题?正在使用不同的值执行相同的SQL语句,这正是您尝试完成的。