美文网首页
scrapy 抓取分页文章合并数据

scrapy 抓取分页文章合并数据

作者: xiaojieluo | 来源:发表于2020-02-01 09:12 被阅读0次

    很多网站为了获取 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

    相关文章

      网友评论

          本文标题:scrapy 抓取分页文章合并数据

          本文链接:https://www.haomeiwen.com/subject/vvytxhtx.html