Selenium爬取结果转DataFrame写入Azure MySQL出现长度不匹配报错
错误根源
pd.read_html()接口返回值为DataFrame列表,哪怕页面仅匹配到1个表格,也会返回长度为1的列表,这就是你执行len(df)得到1的原因,你之前打印的df[0]就是已经解析完成的、结构完整的目标表格DataFrame,无需二次转换。- 报错的直接诱因是多余的格式转换操作:你将长度为1的df列表嵌套一层列表后生成df2,此时df2仅包含1列,你强行给它赋值9个列名,就触发了列长度不匹配的报错。
修正方案
直接使用df[0]作为待写入库的DataFrame即可,仅需修改原代码中数据转换、列名赋值、数据库引擎配置三部分逻辑,修正后的完整代码如下:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup import pandas as pd import time from sqlalchemy import create_engine # base url baseurl = "https://bitcoincharts.com/charts/bitstampUSD#igDailyztgSzm1g10zm2g25zv" # selenium arguments options = Options() options.add_experimental_option("excludeSwitches", ["enable-logging"]) options.headless = True options.add_argument("--window-size=1920,1200") driver = webdriver.Chrome(options=options, executable_path="C:/Users/mande/OneDrive/Knowledge/Python/chromedriver.exe") # navigates to website driver.get(baseurl) # clicks "show raw data" rawdata = driver.find_element_by_xpath("/html/body/div[5]/div/div[2]/a").click() print("Sleeping 10 seconds") time.sleep(10) print("Continue") soup = BeautifulSoup(driver.page_source, 'lxml') tables = soup.find(id='chart_table') # 取read_html返回的第一个元素,就是目标DataFrame df = pd.read_html(str(tables), header=0)[0] print(df) driver.quit() print(type(df)) print(len(df)) # 直接修改df的列名即可,不需要新建df2 df.columns = ['Rownumber', 'Timestamp', 'Open', 'High', 'Low', 'Close', 'Volume (BTC)', 'Volume (USD)', 'Weighted Price'] # 修正数据库连接串的占位符,否则format参数不生效 engine = create_engine("mysql+pymysql://{user}:{pw}@{hostname}/{db}" .format(user="你的实际用户名", pw="你的实际密码", hostname="你的Azure MySQL主机地址", db="你的实际库名")) # 直接调用df的to_sql方法写入 df.to_sql(name='bitcoin', con=engine, if_exists='append', chunksize=10000, index=False)
内容的提问来源于stack exchange,提问作者ananame111
相关产品推荐
相关产品推荐

