scrapy 如何使用Selenium加速刮擦(多处理)

8ljdwjyq  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(164)

我正在尝试从一个url列表中抓取一个单一的数据点到动态加载的站点。我已经用selenium实现了一个抓取器,但是它太慢了。我尝试使用scrapy,但是意识到scrapy不适用于动态加载的站点。我看过关于使用scrapy的splash的文档-但是这似乎是splash加载一个动态站点,而scrapy解析来自该站点的数据的情况;我有一个巨大的URL列表。我正在考虑使用mutliprocessing,但不确定从哪里开始/它是否能很好地与 selenium 配合使用。

def get_cost(url):
driver.get(url)
try:
    element = WebDriverWait(driver, 4).until(
        EC.presence_of_element_located((By.XPATH,'/html/body/c-wiz[2]/div/div[2]/c-wiz/div/c-wiz/c-wiz/div[2]/div[2]/ul[1]/li[1]/div/div[2]/div/div[9]/div[2]/span'))
    )
    cost = element.get_attribute('textContent')
except:
    cost = "-"
finally:
    driver.quit()
return cost

这是一个函数,给出一个网址,抓住最便宜的航班成本在网站上。我是非常新的网络刮取,所以我会感谢一些建议与最好的方式前进。

pexxcrt2

pexxcrt21#

此脚本使用threading(而不是multiprocessing)打开浏览器的多个独立窗口(示例)。这意味着函数get_cost中包含的代码在每个窗口中同时运行。
因为每个线程打开一个新窗口,如果你有很多url,你应该一次只打开少量的url,例如一次打开10个url,否则电脑可能会死机。

from selenium import webdriver
import threading

def get_cost(url, costs):

    driver = ...
    driver.get(url)
    try:
        element = WebDriverWait(driver, 4).until(
            EC.presence_of_element_located((By.XPATH,'/html/body/c-wiz[2]/div/div[2]/c-wiz/div/c-wiz/c-wiz/div[2]/div[2]/ul[1]/li[1]/div/div[2]/div/div[9]/div[2]/span'))
        )
        cost = element.get_attribute('textContent')
    except:
        cost = "-"
    finally:
        driver.quit()
    costs.append(cost)

thread_list = []
costs = []
urls = ['...', '...', '...'] # each one is opened in a separate browser)

for idx, url in enumerate(urls):
    t = threading.Thread(name=f'Thread {idx}', target=get_cost, args=(url, costs))
    t.start()
    print(t.name + ' started')
    thread_list.append(t)

# wait for all threads to complete

for thread in thread_list:
    thread.join()

print(costs)

相关问题