Scrapy在使用for循环时返回重复的无序结果,但在使用lin链接时则不返回

2024-06-23 03:01:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Scrapy来爬网一个网站。这是我的代码:

import scrapy

class ArticleSpider(scrapy.Spider):
    name = "article"
    start_urls = [
        'http://www.irna.ir/en/services/161',
    ]

    def parse(self, response):
        for linknum in range(1, 15):
            next_article = response.xpath('//*[@id="NewsImageVerticalItems"]/div[%d]/div[2]/h3/a/@href' % linknum).extract_first()
            next_article = response.urljoin(next_article)
            yield scrapy.Request(next_article)


            for text in response.xpath('//*[@id="ctl00_ctl00_ContentPlaceHolder_ContentPlaceHolder_NewsContent4_BodyLabel"]'):
                yield {
                    'article': text.xpath('./text()').extract()
                        }

            for tag in response.xpath('//*[@id="ctl00_ctl00_ContentPlaceHolder_ContentPlaceHolder_NewsContent4_bodytext"]'):
                yield {
                    'tag1': tag.xpath('./div[3]/p[1]/a/text()').extract(),
                    'tag2': tag.xpath('./div[3]/p[2]/a/text()').extract(),
                    'tag3': tag.xpath('./div[3]/p[3]/a/text()').extract(),
                    'tag4': tag.xpath('./div[3]/p[4]/a/text()').extract()
                        }
            yield response.follow('http://www.irna.ir/en/services/161', callback=self.parse)

但这会在JSON中返回一个奇怪的重复项混合体,无序并经常跳过链接:https://pastebin.com/LVkjHrRt

但是,当我将linknum设置为单个数字时,代码可以正常工作。在

为什么迭代会改变我的结果?在


Tags: textindivforresponsetagarticleextract
1条回答
网友
1楼 · 发布于 2024-06-23 03:01:17

正如@TarunLalwani已经说过的,你目前的做法是不对的。基本上你应该:

  1. parse方法中,提取一个页面上所有文章的链接,并通过一个名为parse_article的回调函数来获取这些链接。在
  2. 仍然在parse方法中,检查加载更多文章的按钮是否存在,如果存在,则生成对模式http://www.irna.ir/en/services/161/pageN的URL的请求。(这可以在浏览器的开发工具中的“网络”选项卡上的“XHR请求”下找到。)
  3. 定义parse_article方法,在该方法中从details页提取文章文本和标记,并最终将其作为项生成。在

以下是最终的蜘蛛:

import scrapy

class IrnaSpider(scrapy.Spider):
    name = 'irna'
    base_url = 'http://www.irna.ir/en/services/161'

    def start_requests(self):
        yield scrapy.Request(self.base_url, meta={'page_number': 1})

    def parse(self, response):
        for article_url in response.css('.DataListContainer h3 a::attr(href)').extract():
            yield scrapy.Request(response.urljoin(article_url), callback=self.parse_article)

        page_number = response.meta['page_number'] + 1
        if response.css('#MoreButton'):
            yield scrapy.Request('{}/page{}'.format(self.base_url, page_number),
                                 callback=self.parse, meta={'page_number': page_number})

    def parse_article(self, response):
        yield {
            'text': ' '.join(response.xpath('//p[@id="ctl00_ctl00_ContentPlaceHolder_ContentPlaceHolder_NewsContent4_BodyLabel"]/text()').extract()),
            'tags': [tag.strip() for tag in response.xpath('//div[@class="Tags"]/p/a/text()').extract() if tag.strip()]
        }

相关问题 更多 >

    热门问题