【问题标题】:My spider is too slow for my needs and I have no idea how to fix it我的蜘蛛对我的需要来说太慢了,我不知道如何解决它
【发布时间】:2021-09-01 16:42:04
【问题描述】:

我是数据抓取的初学者,我想创建一个蜘蛛,它可以检索本地网站上所有可用的工作,给定关键字和城市。

我还想从每个作业中检索数据,所以我必须点击该链接。

我的代码有两个问题,我不知道如何解决(在自己尝试了半天之后) - 每个请求需要 7 秒,这非常慢(如果我有 1-2k 个工作要刮……那可就太多了)。

我已经在网上搜索了如何修复它,并修复了我的选择器 - 现在我认为我只使用了最低限度的选择器,而且还使用了更快的选择器。我也开始使用显式等待而不是隐式等待 - 现在每个请求有 7 秒,但我不知道如何减少它。

另外,我想爬取每一个链接,但如果有的话,我也想去下一页。这就是为什么我的 parse 方法中有两个 yield 语句,但我的方法不起作用。我看不到下一页,我想看。

# -*- coding: utf-8 -*-
import scrapy

from scrapy.spiders.init import InitSpider
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from scrapy.selector import Selector
from scrapy_selenium import SeleniumRequest

class ExampleSpider(InitSpider):
    name = 'example'
    
    def init_request(self):
        yield SeleniumRequest(
            url='https://www.ejobs.ro/',
            wait_time=3,
            callback=self.search
        )

        return self.initialized()

    def search(self, response):
        driver = response.meta['driver']
        search_input = driver.find_element_by_xpath("//input[@id='keyword']")
        search_input.send_keys("programator")

        search_input2 = driver.find_element_by_xpath("//input[@id='s2id_autogen1']")
        search_input2.send_keys("bucuresti")
        selectieOras = driver.find_element_by_xpath("//input[@id='s2id_autogen1_search']")
        selectieOras.send_keys(Keys.ENTER)

        submit = driver.find_element_by_xpath("//button[@id='submit']")
        driver.execute_script("arguments[0].click();", submit)

        try:
            element = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.ID, "searchSection"))
            )
        finally:
            yield SeleniumRequest(
                url=driver.current_url,
                wait_time=3,
                callback=self.parse
            )

    def parse(self, response):  
        driver = response.meta['driver'] 
        try:
            element = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.ID, "searchSection"))
            )
        finally:
            html = driver.page_source
            response_obj = Selector(text=html)
            
            links = response_obj.xpath("//div[@class='jobitem-body']")
            for link in links:
                URL = link.xpath(".//a[contains(@class, 'title')]/@href").get()

                if URL:
                    yield SeleniumRequest(
                        url=URL,
                        wait_time=3,
                        callback=self.parse_res
                    )

            next = response_obj.xpath("//div[@id='searchPagination']/li[@class='next']/a/@href")
            if next:
                hrefLink = next.get()
                yield SeleniumRequest(
                    url=hrefLink,
                    wait_time=3,
                    callback=self.parse
                )

    def parse_res(self, response):
        yield {
            'title': response.xpath("//h1[@class='jobad-title']/text()").get()
        }

有没有办法解决这两个问题?我是网络爬虫的初学者,我已经尝试了所有可以在文档和网上找到的东西,我没有其他想法。

谢谢。

【问题讨论】:

  • 选择器根本不应该有太大/任何区别——如果你在你身边做所有事情,瓶颈将是服务器响应你的请求的速度,这就是你无法控制。理想情况下,您应该与运行服务器的人员交谈,并了解如何获得一个对他们来说有效且吞吐量更高的批量 API。
  • @CharlesDuffy 你能自己调查一下吗?我要抓取的网站是我所在国家/地区非常受欢迎(而且显然相当大)的找工作网站,与他们交谈并不容易。我不知道,我可能在我的代码中做错了什么。 7s/request 是很多时间 - 没有办法降低它吗?另外,你能检查我的分页问题吗?老实说,我认为学习如何从所有页面获取结果同时还跟踪每个链接对我来说是一件很棒的事情,我相信将来我将不得不再次这样做。
  • 看在上帝的份上,他不会做你的工作。我们的工作是为您提供解决问题的提示,而不是完成所有工作。
  • @TimRoberts 我从来没有问过这个问题。我的想法是检查他是否在每个请求中获得相同的时间,以便我知道问题是否在我这边。

标签: python selenium scrapy


【解决方案1】:
  1. 为什么你使用 selenium 请求而不是 scrapy 请求你呢
    需要渲染java脚本吗?
  2. 为什么要使用 wait_time=3 ?你真的需要等那么久吗?
  3. 检查是否需要禁用自动油门?
  4. 可能您还需要在设置中增加并发请求数

【讨论】:

  • 这应该是评论,而不是答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2011-01-03
  • 2018-06-07
  • 1970-01-01
  • 2013-07-30
相关资源
最近更新 更多