Selenium爬取数据存入MySQL表求助:如何存储两列关联数据
How to Insert Paired Race Name and Time Data into MySQL with Selenium
我编写了一段Selenium代码,用于从网站爬取两类数据,目前代码可正常打印出“赛事名称:时间”格式的结果,但我不清楚如何将这些数据存入MySQL的单个表中,该表包含
coursename和time两列,每行对应一组赛事名称与时间。我曾尝试仅存入races列表,但并未成功,想请教应该通过分别存入两个列表还是通过zip配对后的对象来实现,以及具体的操作方法。我的代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait import pandas as pd from numpy import nan import mysql.connector cnx = mysql.connector.connect(user='root', password='*mypassword*', host='127.0.0.1', database='racing') #cnx.close() cursor = cnx.cursor() driver = webdriver.Chrome("/anaconda3/chromedriver") driver.get("https://www.racingpost.com/results/2018-03-20") timeout=10 expand = driver.find_element_by_xpath('/html/body/div[3]/div[1]/main/div/div/div/div/a[2]').click() #all race results races_element = driver.find_elements_by_class_name('rp-timeView__raceName') races = [] for x in races_element: races.append(x.text) time_element = driver.find_elements_by_class_name('rp-timeView__time') times = [] for x in time_element: times.append(x.text) for race, time in zip(races,times): print(race + ': ' + time) cursor.executemany("INSERT INTO racecard (course) VALUES (%s)", races) driver.quit()
解决方案
你的问题核心在于没有正确构造插入所需的数据格式,也没有匹配表的两列字段。我们可以通过zip()将赛事名称和时间配对成元组列表,然后一次性插入到表中,具体步骤如下:
1. 调整SQL插入语句
你的表包含coursename和time两列,所以INSERT语句需要同时指定这两个列,并对应两个占位符:
INSERT INTO racecard (coursename, time) VALUES (%s, %s)
2. 构造符合要求的数据结构
executemany()方法接受的第二个参数是包含多个元组的列表,每个元组对应一行的所有字段值。我们可以用zip(races, times)生成这样的结构,再转换为列表:
race_time_pairs = list(zip(races, times))
3. 执行插入并提交事务
MySQL默认不会自动提交事务,所以插入后需要调用cnx.commit()来确保数据写入数据库,最后别忘了关闭游标和连接。
修改后的完整代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait import pandas as pd from numpy import nan import mysql.connector # 数据库连接 cnx = mysql.connector.connect(user='root', password='*mypassword*', host='127.0.0.1', database='racing') cursor = cnx.cursor() # Selenium爬取数据 driver = webdriver.Chrome("/anaconda3/chromedriver") driver.get("https://www.racingpost.com/results/2018-03-20") timeout=10 expand = driver.find_element_by_xpath('/html/body/div[3]/div[1]/main/div/div/div/div/a[2]').click() # 获取赛事名称列表(用列表推导式简化代码) races_element = driver.find_elements_by_class_name('rp-timeView__raceName') races = [x.text for x in races_element] # 获取赛事时间列表(用列表推导式简化代码) time_element = driver.find_elements_by_class_name('rp-timeView__time') times = [x.text for x in time_element] # 打印验证数据 for race, time in zip(races,times): print(race + ': ' + time) # 构造插入数据并执行 race_time_pairs = list(zip(races, times)) cursor.executemany("INSERT INTO racecard (coursename, time) VALUES (%s, %s)", race_time_pairs) # 提交事务并关闭资源 cnx.commit() # 必须提交才能写入数据库 cursor.close() cnx.close() driver.quit()
关键说明
- 为什么用
zip()配对?因为races和times是一一对应的列表,zip()能把它们按顺序组合成(赛事名称,时间)的元组,正好匹配表的两列。 - 必须调用
cnx.commit():如果省略这一步,数据库不会保存插入的数据,因为MySQL的连接默认处于事务模式,需要手动提交。 - 关闭资源:用完游标和连接后记得关闭,避免资源泄漏。
内容的提问来源于stack exchange,提问作者M. Sprout
相关产品推荐
相关产品推荐

