【问题标题】:Check response before parse in Scrapy spider在 Scrapy 蜘蛛中解析之前检查响应
【发布时间】:2018-07-25 17:13:33
【问题描述】:

我正在从其中抓取数据的网站实施了某种机制,如果它检测到我的请求过于频繁,则帐户被锁定,请求将被重定向到用户验证页面,在该页面需要用户滑动条为了解锁。

selenium ActionChain 可以轻松解决滑动条,但是我不知道在 Scrapy 哪里添加这个功能。

基本上,在我的爬虫蜘蛛中,对于我想要的每个请求:

  1. 检查响应是否为用户验证页面
  2. 如果是用户验证页面,

    一个。我将启动一个 selenium webdriver 并再次发送请求。然后在webdriver中,解决滑动条解锁账号。

    b.让蜘蛛再次使用相同的 url 发送请求,然后蜘蛛不断从响应中抓取数据。

  3. 如果不是用户验证页面,那么爬虫照常从响应中抓取数据。

你看,在第 2 步中,scrapy 蜘蛛需要两次请求相同的 url,而 selenium webdriver 需要请求一次 url。我不确定如何在 scrapy 框架中实现这一点。有什么想法吗?

以下是我的蜘蛛结构,我不确定在哪里添加上述功能。还是应该使用中间件?

class MySpider(scrapy.Spider):
    name = 'my_spider'

    def start_request(self):
        # read urls from external file
        urls = [...] 
        for url in urls:
            yield scrapy.Request(url)  # the response could be a user validation page

    def parse(self, response):
        # parse a valid page and scrape data
        yield item

--- 2018-03-19 更新 ---

我想我找到了实现该功能的更好方法。我最终创建了一个中间件类,以便它可以重用并且代码库是干净的。

【问题讨论】:

    标签: python selenium scrapy


    【解决方案1】:
    class MySpider(scrapy.Spider):
        name = 'my_spider'
    
        def start_request(self):
            # read urls from external file
            urls = [...] 
            for url in urls:
                yield scrapy.Request(url)  # the response could be a user validation page
    
        def parse(self, response):
            # check if it's the user validation page
            # here i assume you know how to judge if it's a user validation page
            if validation page:
                #Selenium goes here
                browser = webdriver.PhantomJS()
                ...
                yield scrapy.Request(browser.current_url)  # send the request again
    
            # not the validation page
            else:
                #parse the data
            yield item
    

    【讨论】:

    • 我需要在yield scrapy.Request(browser.current_url) # send the request again 中添加callback=self.parse 吗?或者parse会在响应中自动调用?
    • 如果我们在yield中不添加callback=self.parse,scrapy会默认调用parse函数。
    • 应该在 yield itemelse: 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    相关资源
    最近更新 更多