使用 Scrapy 规则对 URL 列表中的参数进行爬网迭代

Crawl iterating with a parameter over a list of urls from a rule with Scrapy

我是 Scrapy 和 Python 的新手。我想执行以下操作:

  1. 访问url并获取所有links 包含"shop/products"作为[=的一部分76=]。 link 看起来像:“http://www.example.com/shop/products/category-name

  2. 舍弃 start_urls 的 url,得到总产品数,TOTAL。在代码上 TOTAL = num_items_per_category.

  3. 最后,将"?sort=Top&size=12&start=PARAM"添加到url. PARAM 必须在每次迭代时递增 12,以防 PARAM <= TOTAL。最后的 url 将是“http://www.example.com/shop/products/category-name?sort=Top&size=12&start=PARAM

  4. 从生成的start_urls中获取另一个url并重新开始第2步。


这是我的爬虫代码:

import scrapy
import re
import datetime

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.http.request import Request

class MySpider(CrawlSpider):
    name = 'my_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com/shop/products']
    rules = (
        Rule(LxmlLinkExtractor(
            restrict_xpaths=('.//li[@class="item"]/a')),
            follow=False,
            callback='parse_list'
        ),
     )

    def parse_list(self, response):
        SET_SELECTOR = '.product'
        for item in response.css(ITEM_SELECTOR):
            NAME_SELECTOR = 'div[@class="product"]/h2/a/@title'
            yield {
                'name': item.xpath(NAME_SELECTOR).extract_first()
            }

        NUM_ITEMS_PER_CATEGORY_SELECTOR = 'div[@id="search"]/@data-count'
        num_items_per_category = item.xpath(NUM_ITEMS_PER_CATEGORY_SELECTOR).extract_first()
        nipc = int(0 if num_items_per_category is None else num_items_per_category)
        try:
            next_start = response.meta["next_start"]
        except KeyError:
            next_start = 0
        if next_start <= nipc:
            yield scrapy.Request(
                response.urljoin('%s?sort=Top&size=12&start=%s' % (response.url, next_start)),
                meta={"next_start": next_start + 12},
                dont_filter=True,
                callback = self.parse_list
            )

问题是:

  1. 我不知道它是否存在任何 css select 或正则表达式用于 select 每个 link 我想。在代码上,我访问的路径我知道有一些我想要的 link,但页面上还有更多。

  2. 代码未按预期运行。似乎 next_start 没有在每次迭代中递增 12。该代码仅获取生成的 start_urls 列表中每个 url 的前 12 个元素。我是否正确使用了 meta 变量?或者我可能需要每个类别页面的另一个第一个片段来获得总计数,然后才能使用它来迭代它?或者,也许我需要另一种使用 start_requests 的方法...你怎么看?

你的蜘蛛所做的就是访问 url http://www.example.com/shop/products,提取 <li class="item"> 元素内的所有链接并使用 parse_list 回调获取所有链接。正如我所见,这不是您正在等待的行为 - 相反,您应该使用一些开始 url 包含种子 URLs 和 Extractor with allow=r"shop/products" 在规则中。

这部分 '%s?sort=Top&size=12&start=%s' % (response.url, next_start) 也是错误的,因为 response.url 包含完整的 URL,包括 GET 参数,因此每次您将带有参数的部分附加到现有参数字符串时,就像这样 ?sort=Top&size=12&start=0?sort=Top&size=12&start=12?sort=Top&size=12&start=24.在附加新字符串之前清除 url 中的参数,或者只使用 FormRequest 作为传递参数的更方便的方式。

顺便说一句,Scrapy 有非常方便的交互式控制台用于调试目的,您可以使用 scrapy.shell.inspect_response.

从 spider 的任何部分调用它