爬取伯乐在线文章(三)爬取所有页面的文章

讨论QQ:1586558083

 

正文

爬取所有页面

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

修改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+"\t"+"发布时间:"+date+"\t"+str(praise_num)+"点赞"+"\t"+str(collect_num)+"收藏"+"\t"+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", "")

 

posted @   扎心了,老铁  阅读(1734)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示