zoukankan      html  css  js  c++  java
  • 爬取伯乐在线文章(三)爬取所有页面的文章

    爬取所有页面

    之前只是爬取某一篇文章的内容,但是如何爬取所有文章

    修改start_urls = ['http://blog.jobbole.com/all-posts/']

    重新启动scrapy的shell

    parse函数需要做两件事

    1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
    2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse

    获取列表页中的所有文章URL

    post_urls = response.css('#archive .floated-thumb .post-thumb a::attr(href)').extract()

    获取所有URL之后将其交给scrapy进行下载并解析,如何交给scrapy进行下载,下载完成之后调用我们自己定义的解析函数,这就需要用到scrapy的另一类Request,在scrapy.http里面

        def parse(self, response):
            '''
            1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
            2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse
            '''
    
            #  解析列表页中的所有文章的URL并交给scrapy下载后并解析
            post_urls = response.css('#archive .floated-thumb .post-thumb a::attr(href)').extract()
            for post_url in post_urls:
                Request(url=post_url, callback=self.parse_detail)
                print(post_url)
                pass
        def parse_detail(self,response):
            #提取文章的具体逻辑
            title = response.xpath('//*[@id="post-110287"]/div[1]/h1/text()').extract()[0]
            date = response.xpath('//*[@id="post-110287"]/div[2]/p/text()').extract()[0].strip().replace("·", "")
            praise_num = response.xpath('//*[@id="110287votetotal"]/text()').extract()[0]
            collect_num = response.xpath('//*[@id="post-110287"]/div[3]/div[9]/span[2]/text()').extract()[0].split(" ")[1]
            comment_num = response.xpath('//*[@id="post-110287"]/div[3]/div[9]/a/span/text()').extract()[0].split(" ")[1]
    
            pass

    可能有些网站获取的URL里面只有/114466/,这是就需要当前的URL和获取的URL进行一个拼接从而形成完整的URL,这就需要用到urllib中的parse函数,将Request交给scrapy进行下载使用yield关键字

        def parse(self, response):
            '''
            1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
            2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse
            '''
    
            #  解析列表页中的所有文章的URL并交给scrapy下载后并解析
            post_urls = response.css('#archive .floated-thumb .post-thumb a::attr(href)').extract()
            for post_url in post_urls:
                yield Request(url=parse.urljoin(response.url, post_url), callback=self.parse_detail)
                

    还需要提取下一页并交给scrapy进行下载

        def parse(self, response):
            '''
            1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
            2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse
            '''
    
            #  解析列表页中的所有文章的URL并交给scrapy下载后并解析
            post_urls = response.css('#archive .floated-thumb .post-thumb a::attr(href)').extract()
            for post_url in post_urls:
                yield Request(url=parse.urljoin(response.url, post_url), callback=self.parse_detail)
    
            #  提取下一页并交给scrapy进行下载
            next_url = response.css('.next.page-numbers::attr(href)').extract_first()
            if next_url:
                yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse)

    所有代码如下

    # -*- coding: utf-8 -*-
    import scrapy
    import re
    from scrapy.http import Request
    from urllib import parse
    
    
    class JobboleSpider(scrapy.Spider):
        name = 'jobbole'
        #允许的域名
        allowed_domains = ['blog.jobbole.com']
        #起始的url
        start_urls = ['http://blog.jobbole.com/all-posts/']
    
        #业务逻辑
        def parse(self, response):
            '''
            1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
            2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse
            '''
    
            #  解析列表页中的所有文章的URL并交给scrapy下载后并解析
            post_urls = response.css('#archive .floated-thumb .post-thumb a::attr(href)').extract()
            for post_url in post_urls:
                yield Request(url=parse.urljoin(response.url, post_url), callback=self.parse_detail)
    
            #  提取下一页并交给scrapy进行下载
            next_url = response.css('.next.page-numbers::attr(href)').extract_first()
            if next_url:
                yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse)
    
    
        def parse_detail(self,response):
            print("目前爬取的URL是:"+response.url)
            #提取文章的具体逻辑
    
            #  获取文章标题
            title = response.css('.entry-header h1::text').extract()[0]
            #  获取发布日期
            date = response.css('.entry-meta .entry-meta-hide-on-mobile::text').extract()[0].strip().replace("·", "")
            #  获取点赞数
            praise_num = response.css('.vote-post-up h10::text').extract()[0]
            #  获取收藏数
            collect_num = response.css('.post-adds .bookmark-btn::text').extract()[0].split(" ")[1]
            collect_match_re = re.match(r'.*?(d+).*', collect_num)
            if collect_match_re:
                collect_num = int(collect_match_re.group(1))
            else:
                collect_num = 0
            #  获取评论数
            comment_num = response.css('.post-adds .hide-on-480::text').extract()[0]
            comment_match_re = re.match(r'.*?(d+).*', comment_num)
            if comment_match_re:
                comment_num = int(comment_match_re.group(1))
            else:
                comment_num = 0
    
            content = response.css('div.entry').extract()[0]
    
    
            print(title+"	"+"发布时间:"+date+"	"+str(praise_num)+"点赞"+"	"+str(collect_num)+"收藏"+"	"+str(comment_num)+"评论")
            #date = response.xpath('//*[@id="post-110287"]/div[2]/p/text()').extract()[0].strip().replace("·", "")
            #praise_num = response.xpath('//*[@id="110287votetotal"]/text()').extract()[0]
            #collect_num = response.xpath('//*[@id="post-110287"]/div[3]/div[9]/span[2]/text()').extract()[0].split(" ")[1]
            #comment_num = response.xpath('//*[@id="post-110287"]/div[3]/div[9]/a/span/text()').extract()[0].split(" ")[1]
    View Code

    爬取图片

    爬取图片通过Request传入response,在Request的meta参数

    #业务逻辑
        def parse(self, response):
            '''
            1. 获取文章列表页中的文章URL并交给scrapy下载后并解析
            2. 获取下一页的URL并交给scrapy进行下载,下载完成后交给parse
            '''
    
            #  解析列表页中的所有文章的URL并交给scrapy下载后并解析
            post_nodes = response.css('#archive .floated-thumb .post-thumb a')
    
            for post_node in post_nodes:
                image_url = post_node.css("img::attr(src)").extract_first("")
                post_url = post_node.css("::attr(href)").extract_first("")
                yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url":image_url}, callback=self.parse_detail)
    
            #  提取下一页并交给scrapy进行下载
            next_url = response.css('.next.page-numbers::attr(href)').extract_first()
            if next_url:
                yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse)

    通过response获取图片

    front_image = response.meta.get("front_image_url", "")
  • 相关阅读:
    C#中Equals和= =(等于号)的比较)(转载)
    C# 控制台应用程序输出颜色字体
    c#获取当前运行程序所在的目录
    java环境配置
    c#随机产生颜色
    Git学习
    git删除所有提交历史记录
    git忽略项gitegnore配置
    不搭建git服务器对git仓库进行局域网内共享多人合作开发项目
    搭建Git服务器-SCM-Manager
  • 原文地址:https://www.cnblogs.com/qingyunzong/p/9909232.html
Copyright © 2011-2022 走看看