【问题标题】:Scrape a single link with Scrapy使用 Scrapy 抓取单个链接
【发布时间】:2018-12-23 15:17:14
【问题描述】:

我正在搜索 dior.com 的产品。 head/script 为我提供了我需要的所有字段,除了产品描述。要抓取描述,我需要点击链接(下面代码中的 url 变量)。我熟悉的唯一方法是使用 BeautifulSoup。我可以只使用 Scrapy 解析它吗? 谢谢各位。

class DiorSpider(CrawlSpider):
    name = 'dior'
    allowed_domains = ['www.dior.com']
    start_urls = ['https://www.dior.com/en_us/']
    rules = (
        Rule(LinkExtractor(allow=(r'^https?://www.dior.com/en_us/men/clothing/new-arrivals.*',)), callback='parse_file')
    )

    def parse_file(self, response):
        script_text = response.xpath("//script[contains(., 'window.initialState')]").extract_first()
        blocks = extract_blocks(script_text)
        for block in blocks:
            sku = re.compile(r'("sku":)"[a-zA-Z0-9_]*"').finditer(block)
            url = re.compile(r'("productLink":{"uri":)"[^"]*').finditer(block)
            for item in zip(sku, url):
                scraped_info = {
                    'sku': item[0].group(0).split(':')[1].replace('"', ''),
                    'url': 'https://www.dior.com' + item[1].group(0).split(':')[2].replace('"', '')
                }

                yield scraped_info

【问题讨论】:

  • 为什么不简单地跟随 url 链接并在另一个函数中解析呢?例如yield Request(scraped_info[url],callback=self.another_parse)
  • 你没有问这个,但你到底为什么要在 JSON 键上使用正则表达式组,然后进行字符串拆分,而不是让正则表达式提取你真正想要的值:@ 987654323@ 然后item[0].group(1) 包含没有戏剧性的sku?
  • 另外,就目前的网站而言,您只需一个小替代品就可以将该文本输入json.loads 并且根本不必使用正则表达式 - 这是迄今为止更好的结果:data = json.loads(re.replace(r"\s*window.initialState\s*=\s*", "", script_text))
  • 谢谢马修·L·丹尼尔。该脚本文本包含页面上的所有产品,我想将这一大块分成更小的块,以便一个块只包含一个产品。然后我迭代它们以收集必要的字段,但有些字段缺少脚本文本,所以我需要按照我已经定义的 url 进入产品页面并提取缺少的内容。我的逻辑对吗?

标签: python web-scraping beautifulsoup scrapy


【解决方案1】:

如果您需要从第二个请求中提取其他信息,而不是在那里产生数据,您应该产生一个对 URL 的请求,其中包含您已经在 Request.meta 属性中提取的信息。

from scrapy import Request

# …

    def parse_file(self, response):
        # …
        for block in blocks:
            # …
            for item in zip(sku, url):
                # …
                yield Request(url, callback=self.parse_additional_information, meta={'scraped_info': scraped_info}

    def parse_additional_information(self, response):
        scraped_info = response.meta['scraped_info']
        # extract the additional information, add it to scraped_info
        yield scraped_info

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多