【问题标题】:Scraping many pages using scrapy使用scrapy抓取许多页面
【发布时间】:2015-01-05 12:49:26
【问题描述】:

我正在尝试使用 scrapy 抓取多个网页。页面链接如下:

http://www.example.com/id=some-number

在下一页中,末尾的数字减少了 1

所以我正在尝试构建一个可以导航到其他页面并抓取它们的蜘蛛。我的代码如下:

import scrapy
import requests
from scrapy.http import Request

URL = "http://www.example.com/id=%d"
starting_number = 1000
number_of_pages = 500
class FinalSpider(scrapy.Spider):
    name = "final"
    allowed_domains = ['example.com']
    start_urls = [URL % starting_number]

    def start_request(self):
        for i in range (starting_number, number_of_pages, -1):
            yield Request(url = URL % i, callback = self.parse)

    def parse(self, response):
        **parsing data from the webpage**

这进入了一个无限循环,在打印页码时我得到了负数。我认为这是因为我在我的 parse() 函数中请求一个页面。

但是here 给出的示例可以正常工作。我哪里错了?

【问题讨论】:

    标签: python web-scraping scrapy


    【解决方案1】:

    请求的第一个页面是“http://www.example.com/id=1000”(starting_number

    它的响应通过parse()for i in range (0, 500): 您正在请求http://www.example.com/id=999http://www.example.com/id=998http://www.example.com/id=997...http://www.example.com/id=500

    self.page_number 是一个蜘蛛属性,所以当你减少它的值时,你在第一个 parse() 之后有 self.page_number == 500

    因此,当 Scrapy 调用 parse 以获得 http://www.example.com/id=999 的响应时,您正在生成对 http://www.example.com/id=499http://www.example.com/id=498http://www.example.com/id=497...http://www.example.com/id=0 的请求

    你猜第三次会发生什么:http://www.example.com/id=-1http://www.example.com/id=-2...http://www.example.com/id=-500

    对于每个响应,您将生成 500 个请求。

    你可以通过测试self.page_number >= 0来停止循环


    在 cmets 中的 OP 问题后编辑:

    不需要多个线程,Scrapy 异步工作,您可以将所有请求排入一个重写的 start_requests() 方法中(而不是请求 1 页,然后在 Request 方法中返回 Request 实例)。 Scrapy 将接受足够多的请求来填充它的管道、解析页面、选择要发送的新请求等等。

    start_requests documentation

    这样的事情会起作用:

    class FinalSpider(scrapy.Spider):
        name = "final"
        allowed_domains = ['example.com']
        start_urls = [URL % starting_number]
        def __init__(self):
            self.page_number = starting_number
    
        def start_requests(self):
            # generate page IDs from 1000 down to 501
            for i in range (self.page_number, number_of_pages, -1):
                yield Request(url = URL % i, callback=self.parse)
    
        def parse(self, response):
            **parsing data from the webpage**
    

    【讨论】:

    • 您的方法非常有效。有没有其他方法可以做到这一点,可能运行多个线程?上面有什么?
    • 它不工作。它刮掉第一页然后退出。我将编辑蜘蛛的代码来说明。
    • 什么是“此方法必须返回一个迭代器,其中包含第一个为该蜘蛛爬行的请求。”究竟是什么意思?我认为这可能是错误。有什么想法吗?
    • 你写的是 'start_request' 而不是 'start_requests'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多