scrapy 抓取分页文章合并数据

很多网站为了获取 pv, 会把一篇完整的文章分成多页, 这也给爬虫抓取造成了一些小问题。


分页文章

常规的做法是先解析第一页数据,保存到 item , 再检测是否存在下一页, 如果存在,重复执行抓取函数, 直到到最后一页停止。
但是在scrapy 中有一个问题, scrapy 中的回调函数无法返回值,抓取的文章正文无法返回, 所以这里可以用 request 的 meta 属性单向传递item变量到抓取函数中。

def parse_article(self, response):
        """parse article content
        Arguments:
            response {[type]} -- [description]
        """
        selector = Selector(response)
        article = ArticleItem()
        # 先获取第一页的文章正文
        article['content'] = selector.xpath(
            '//article[@class="article-content"]').get()
        
        # 拆分最后一页的 url, 可以得到文章的base url 和总页数
        page_end_url = selector.xpath(
            '//div[@class="pagination"]/ul/li/a/@href').extract()[-1]
        page_base_url, page_count = re.findall(
            '(.*?)_(.*?).html', page_end_url)[0]
        page_count = int(page_count)
        for page in range(2, page_count + 1):
            # 构造出分页 url
            url = page_base_url + '_{}.html'.format(page)
            # 手动生成 Request 请求, 注意函数中的 priority 参数, 代表了 Request 是按顺序执行的, 值越大, 优先级越高
            request = Request(url=url, callback=self.parse_content, priority=-page)
            # 向 self.parse_content 函数传递 item 变量
            request.meta['article'] = article
            yield request

self.parse_content 中主要是抓取文章正文, 并存入 item 的操作

def parse_content(self, response):
        selector = Selector(response)
        article = response.meta['article']
        # 注意这里对 article['content']的操作是 +=, 这样不会清空上一页保存的数据
        article['content'] += selector.xpath('//article[@class="article-content"]').get()
        yield article

Reference: Requests and Responses

https://www.jianshu.com/p/3810309e3f54

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论