前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Scrapy实战8: Scrapy系统爬取伯乐在线

Scrapy实战8: Scrapy系统爬取伯乐在线

作者头像
龙哥
发布2020-02-12 11:16:11
5860
发布2020-02-12 11:16:11
举报
文章被收录于专栏:Python绿色通道Python绿色通道

一、前言

上一篇给大家仔细讲解了如何用Xpath分类爬取医疗信息网站医疗器材名称和介绍图片,以及三种最常用的存储方法。

本篇是本系列的第八篇了,今天给大家讲讲如何用Scrapy系统爬取伯乐在线文章信息。

二、你不得不知道的 Knowledge

1.CSS选择器获取标签内容值和标签属性值
代码语言:javascript
复制
eg. <a href = "https://blog.csdn.net/qq_39241986">极简XksA的博客</a>
# 1.获取标签里的内容值
response.css("a::text").extract()
极简XksA的博客
# 2.获取href属性值
response.css("a::attr(href)")
https://blog.csdn.net/qq_39241986
2.urllib包下的parse函数作用
代码语言:javascript
复制
# python3下
from urllib import parse
url_main = "https://blog.csdn.net"
post_url = "/qq_39241986"
'''
urljoin函数参数介绍:
    url_main :第一个参数为主域名;
    post_url :第二个参数为需补全部分;
'''
url= parse.urljoin(url_main,post_url)
print(url)
# result :
#     https://blog.csdn.net/qq_39241986

通过代码容易看出,urllib包下的parse函数作用是能够补全我们获取的不完全链接(在上一篇中我们获取到的商品类别url就是不完全的url,当时是我们自己写方法修正的数据)

3.yield关键字介绍

一个带有 yield 的函数就是一个 generator(生成器),它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。

三、看代码,边学边敲边记Scrapy爬取伯乐在线

1.爬取逻辑思路分析

爬取逻辑思路

图上已经绘画和写的比较清楚了,一个简单思路就是:请求页面 -> 获取文章和下页链接 -> 获取文章详细信息 -> 翻页,再从头开始,一直到爬完所有页面,所有文章,下面我们具体动手试试。

2.调试方便,我们还是在cmd下用scrapy shell 进行调试
(1)获取主页面所有文章的url

1)页面分析:

页面分析文章url获取方法

通过图片上面标记,容易看出,我们要获取的文章url在 id 为archive的div下的class为post floated-thumb的div下的class为post-thumb的div下的a标签的href属性中,哈哈,读起来有点拗口,这里提供两种方法获取相应内容:

Xpath路径:

代码语言:javascript
复制
'//*[@id="archive"]/div/div[1]/a/@href'

CSS选择器:

代码语言:javascript
复制
# 注:因为post floated-thumb这个类名中 post和floated-thumb中间有个空格,表示两个类名,
# 我们可以直接根据后面部分来查找到这个class。(attr用来取属性值)
"#archive .floated-thumb .post-thumb a::attr(href)"

2)shell下运行结果

代码语言:javascript
复制
# 我选择的是Xpath获取,个人比较习惯
>>> response.xpath('//*[@id="archive"]/div/div[1]/a/@href').extract()
['http://blog.jobbole.com/114334/', 'http://blog.jobbole.com/114331/', 'http://blog.jobbole.com/114329/', 'http://blog.jobbole.com/114327/', 'http://blog.jobbole.com/114324/', 'http://blog.jobbole.com/114321/', 'http://blog.jobbole.com/114319/', 'http://blog.jobbole.com/114311/', 'http://blog.jobbole.com/114308/', 'http://blog.jobbole.com/114303/', 
'http://blog.jobbole.com/114297/', 'http://blog.jobbole.com/114285/', 'http://blog.jobbole.com/114283/', 'http://blog.jobbole.com/114280/', 'http://blog.jobbole.com/114276/', 'http://blog.jobbole.com/114273/', 'http://blog.jobbole.com/114270/', 'http://blog.jobbole.com/114268/', 'http://blog.jobbole.com/114261/', 'http://blog.jobbole.com/114168/']
(2)获取翻页链接

1)页面分析:

页面分析获取翻页链接url

通过图片上面标记,容易看出,我们要获取的翻页url在class为next page-numbers的a标签的href属性中,中这里提供两种方法获取相应内容: Xpath路径:

代码语言:javascript
复制
'//*[@id="archive"]/div[21]/a[4]/@href'

CSS选择器:

代码语言:javascript
复制
# 页面上查找发现,next 属性值是唯一的,
# 所以可以直接根据类名next来查找下一页的url。
".next::attr(href)"

2)shell下运行结果

代码语言:javascript
复制
# 我选择的是CSS选择器获取,一眼看出比较简单嘛
>>> response.css(".next::attr(href)").extract()[]
'http://blog.jobbole.com/all-posts/page/2/'
3.在Pycharm下实操代码
(1)基础代码
代码语言:javascript
复制
# -*- coding: utf-8 -*-
import scrapy
import re
# 发送请求爬取页面
from scrapy.http import Request
# 归正url
from urllib import parse
# 爬虫类
class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    start_urls = ['http://blog.jobbole.com/all-posts/']

(2)获取文章url下载和翻页下载代码
代码语言:javascript
复制
# 爬取页面所有文章url和翻页url
# 翻页下载
def parse(self, response):
    # 1.获取单页面文章url
    post_urls = response.xpath('//*[@id="archive"]/div/div[1]/a/@href').extract()
    # 2.下载文章url
    for post_url in post_urls:
        yield Request(url= parse.urljoin(response.url,post_url),callback= self.parse_detail)
    # 3.获取翻页url和翻页下载
    next_url = response.css(".next::attr(href)").extract()
    if next_url != []:
        next_url = next_url[]
        yield Request(url= parse.urljoin(response.url,next_url),callback= self.parse)
(3)解析单篇文章信息
代码语言:javascript
复制
# 获取单篇文章详情信息
def parse_detail(self,response):
    # 文章标题
    title = response.css(".entry-header h1 ::text").extract()[]

    # 发布日期
    data_r = response.css(".entry-meta-hide-on-mobile::text").extract()[].strip()
    data_time = data_r.replace('·','').strip()

    # 文章分类
    article_type = response.css("p.entry-meta-hide-on-mobile a::text").extract()
    if article_type != []:
        article_type = ",".join(article_type)

    # 点赞数
    praise_number = response.css(".href-style.vote-post-up h10::text").extract()
    if praise_number != [] :
        praise_number = int(praise_number[])
    else:
        praise_number = 

    # 收藏数
    collection_str = response.css("span.btn-bluet-bigger:nth-child(2)::text").extract()[]
    reg_02 = '.*?(\d+).*'
    collection_number = re.findall(reg_02, collection_str)
    if collection_number:
        collection_number = int(collection_number[])
    else:
        collection_number = 

    # 评论数
    comment_number = response.css("a[href='#article-comment'] span::text").extract()[]
    comment_number = re.findall(reg_02, comment_number)
    if comment_number:
        comment_number = int(comment_number[])
    else:
        comment_number = 

    print("文章标题:"+title)
    print("发布日期:"+data_time)
    print("文章分类:"+article_type)
    print("点赞数:"+str(praise_number))
    print("收藏数:"+str(collection_number))
    print("评论数:"+str(comment_number))
    print("----------------------------------------")
(4)整合上面(1)、(2)、(3)后在pycharm下运行效果

我运行了差不多7-9秒,目测爬取了100条信息应该有,所以在爬取速度和可靠性上,依靠框架爬取要比自己request好的多嘿。

运行部分截图

代码语言:javascript
复制
文章标题:泪流满面的  个 Git 面试题
发布日期://
文章分类:IT技术,Git
点赞数:
收藏数:
评论数:
----------------------------------------
文章标题:设计微服务的最佳实践
发布日期://
文章分类:IT技术,微服务
点赞数:
收藏数:
评论数:
----------------------------------------
···
文章标题:如何自动唤醒和关闭 Linux
发布日期://
文章分类:IT技术,Linux
点赞数:
收藏数:
评论数:
----------------------------------------
文章标题:他们是优秀的前端,所以这些后端工作也交给他们…
发布日期://
文章分类:职场,程序员
点赞数:
收藏数:
评论数:
----------------------------------------

四、后言

通过本次学习,不知道大家有没有对Scrapy有多一点点了解嘿,通过本次学习我知道了如何把页面发送给Scrapy,让它帮忙下载,即使是几千条数据,也没有出现连接错误,同时知道了关键字yield的基本使用方法,我觉得最重要的是我们爬取的思路,以及在爬取过程中如何选取更加适合的匹配方法(目前我们已经讲了:正则、Xpath、CSS选择器)。

继续加油,下一节我们将讲解如何设计数据库来存储我们获取的数据,并利用items方法交给pipelines进行数据存储和查重。

【完】

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python绿色通道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、你不得不知道的 Knowledge
    • 1.CSS选择器获取标签内容值和标签属性值
      • 2.urllib包下的parse函数作用
        • 3.yield关键字介绍
        • 三、看代码,边学边敲边记Scrapy爬取伯乐在线
          • 1.爬取逻辑思路分析
            • 2.调试方便,我们还是在cmd下用scrapy shell 进行调试
              • (1)获取主页面所有文章的url
              • (2)获取翻页链接
            • 3.在Pycharm下实操代码
              • (1)基础代码
              • (2)获取文章url下载和翻页下载代码
              • (3)解析单篇文章信息
              • (4)整合上面(1)、(2)、(3)后在pycharm下运行效果
          • 四、后言
          相关产品与服务
          数据保险箱
          数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档