【发布时间】:2021-09-05 14:39:50
【问题描述】:
我正在抓取数据,并且每次都需要保存它,以避免丢失我已经完成的内容。 我的代码是这样的:
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
import time
import pandas as pd
from random import randrange
def crawl(df):
chrome_options = webdriver.ChromeOptions()
my_list1=[]
my_list2=[]
# Server info
query=df['Source'].unique().tolist()
driver=webdriver.Chrome('path',chrome_options=chrome_options)
driver.maximize_window()
for x in query:
response=driver.get('link_to_scrape/'+x)
try:
wait = WebDriverWait(driver, 30)
time.sleep(randrange(5))
driver.execute_script("window.scrollTo(0, 1000)")
# Get data to append in my_list1
my1 = wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Trustscore']/../following-sibling::div/descendant::div[@class='icon']"))).text
my_list1.append(my1)
# Get data to append in my_list2
try:
my2 = wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Company data']/../following-sibling::div/descendant::b[text()='Alexa rank']/../following-sibling::div"))).text
my_list2.append(my2)
except:
my_list2.append("Data not available")
except:
print("\n!!! ERROR !!!")
break
# Create dataframe
dict = {'Source': query, 'List 1': my_list1, 'List 2': my_list2}
df=pd.DataFrame.from_dict(dict)
driver.quit()
return df
目前,代码有一些弱点,我需要通过在关闭查询中每个元素的会话之前保存数据来解决这些弱点。
假设我在df['Source']: x1,x2,x3,x4,x5 中有 5 个元素。
当我运行我的代码时,x1 被保存,但是当代码使用 x2 运行时,我收到错误:ValueError: arrays must be all be the same length,并且进程停止。 我想解决这个问题如下:
- 对于
df['Source']中的每个唯一元素,打开chrome,提取数据,将数据保存到df,然后关闭chrome 窗口; - 等待 15 秒再提交新请求;
- 提交新请求:为
df['Source']中的第二个元素打开 chrome,提取数据,将数据保存在之前使用的相同 df 中(对于元素 x1),关闭 chrome。 - 以此类推,直到所有元素都在新的 df 中。
为了保留提取数据,我需要在每一步更新 df,而不是在最后更新,即当 crawl 提取列表中所有每个项目的数据时。 我的代码没有这样做:它在最后创建 df,所以每次我遇到错误时,我都会丢失我的工作。 最后,我应该有一个包含 5 行(不包括标题)的数据框,其中提取了数据(或错误消息,如果它运行异常)。 您能否为我提供一些帮助以了解打开/关闭 chrome 并在每次迭代时使用新数据保存/更新数据框的正确方法?如果您需要更多信息,请告诉我。
【问题讨论】:
标签: python pandas web-scraping selenium-chromedriver