Scrapy爬取伯乐在线所有文章

本文详述了使用Scrapy框架爬取伯乐在线所有文章的步骤,包括项目搭建、目标网站分析、XPath解析、数据保存到JSON和MySQL数据库。还介绍了图片下载、异步操作以及Item Loader机制,提供了调试技巧和解决问题的经验分享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

准备工作

1.scrapy目录结构介绍

在这里插入图片描述
很多用法与Django很类似

scrapy 架构:

在这里插入图片描述

  • Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等
  • Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎
  • Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理
  • Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器).
  • Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方
  • Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件
  • Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
Scrapy的运作流程:

在这里插入图片描述

几个常用命令:

#新建项目工程
scrapy startproject 工程名称

#新建一个爬虫
scrapy genspider 爬虫名 域名

#在终端中调试
scrapy shell 爬取链接
2.目标网站分析

这次要爬取的是伯乐在线,伯乐在线中有大量高质量的文章,我们要爬取的就是所有文章。
由于伯乐在线提供了一个全部文章的url( http://blog.jobbole.com/all-posts/ ),用这个url抓取更有效率,所以我们就不用考虑采用深度优先或者广度优先的爬取算法了。
伯乐在线所有文章
有了这个全部文章的url,我们便利了很多。
但是获取所有页面的文章,仍然存在两种爬虫策略,还需要我们做出选择:

  • 更改url中的页码信息:http://blog.jobbole.com/all-posts/page/页码数/
  • 获取“下一页”的url信息
    在这里插入图片描述
    更改url页码虽然很方便,但是并不能一劳永逸,因为我们不确定总页数。
    所以,这次我们选择的是获取“下一页”url的方式,去遍历所有的页面。

scrapy 项目搭建

1.新建scrapy 项目

依次执行以下命令,新建scrapy项目与爬虫

scrapy startproject ArticleSpider #新建scrapy项目
scrapy genspider jobbole blog.jobbole.com #新建爬虫

然后我们就能看到多了一个ArticleSpider的项目工程以及jobbole爬虫文件
项目工程
jobbole爬虫

2.scrapy 调试

pycharm没有scrapy的模板,这里给大家介绍一个调试的技巧。
在项目中新建一个main文件,代码如下:

# main.py
from scrapy.cmdline import execute
import sys
import os

sys.path.append(os.path.dirname(os.path.abspath(__file__)))
#os.path.dirname(os.path.abspath(__file__)) 获取当前目录下的父目录
execute(["scrapy","crawl","jobbole"]) #执行命令 scrapy crawl jobbole

直接在main文件中运行,就可以进行调试了。
好了,现在我们来Debug一下。
在jobbole.py中打上断点,可以看到parse函数中response的信息。
在这里插入图片描述

有了调试的模块,我们开发爬虫项目的效率就能提高许多。

3.解析数据

首先,我们明确需要提取的数据:标题、标签、正文、时间、点赞数、评论数

xpath介绍

我们这次使用的是xpath解析数据,下面来介绍下xpath

xpath节点关系
xpath语法
在这里插入图片描述
在这里插入图片描述

使用xpath实现字段解析

通过分析网页结构,利用xpath获取我们想要的文章信息:

    def parse(self, response):
        title = response.xpath('//div[@class="entry-header"]/h1/text()').extract_first() #文章标题
        create_time = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/text()').extract_first().strip().replace('·','') #发表时间
        praise_nums = response.xpath('//span[contains(@class,"vote-post-up")]/h10/text()').extract_first() #点赞数
        fav_nums = response.xpath('//span[contains(@class,"bookmark-btn")]/text()').extract_first() #收藏数
        match_re = re.match(".*(\d+).*",fav_nums)
        if match_re:
            fav_nums = match_re.group(1)

        comment_nums = response.xpath('//a[@href="#article-comment"]/span/text()').extract_first() #评论数
        match_re = re.match(".*(\d+).*",comment_nums)
        if match_re:
            comment_nums = match_re.group(1)

        content = response.xpath('//div[@class="entry"]').extract_first() #文章内容
        tag_list = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/a/text()').extract() 
        tag_list = [element for element in tag_list if not element.strip().endswith("评论")] #去掉以“评论”结尾的标签
        tags = ",".join(tag_list) #文章标签

注意:通过F12看到的代码是已经渲染完成后的结果;而查看网页源代码是js生成之前的,有可能与前者不一样。

编写spider爬取所有的文章

我们上面只是解析了一篇文章的信息,但是要将所有文章的信息爬取下来,就需要对上面的代码进行修改:

# -*- coding: utf-8 -*-
#jobbole.py


import scrapy
import re
from scrapy.http import Request
from urllib import parse


class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    start_urls = ['http://blog.jobbole.com/all-posts/']

    def parse(self, response):
        '''
        1.获取文章列表页中的文章url并交给scrapy下载后进行解析
        2.获取下一页的url并交给scrapy进行下载,下载完成后交给parse
        :param response:
        :return:
        '''
        #解析列表页中所有文章的url
        post_nodes = response.xpath('//div[@id="archive"]/div[@class="post floated-thumb"]/div[@class="post-thumb"]/a')
        for post_node in post_nodes:
            image_url = post_node.xpath("./img/@src").extract_first("") #默认为空
            post_url = post_node.xpath(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值