前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >requests+pyquery爬取csdn博客信息

requests+pyquery爬取csdn博客信息

作者头像
月小水长
发布2019-07-31 15:49:37
7680
发布2019-07-31 15:49:37
举报
文章被收录于专栏:月小水长

突然闲来无事想要爬取csdn博客,顺便温习下相关技术点。

爬取目标

以我的csdn主页为例

爬取的主要的数据已经在上用红线图标出来了,主要可分为两部分

  1. 所有博客的八个统计数据,原创的博客数、你的粉丝数、博客获得的赞、博客的评论数、博客等级、访问量、积分和排名
  2. 每篇博客的具体信息,如标题、发布时间、阅读数、评论数

思路分析

Google Chrome浏览器F12开发者工具查看网页结构,比较简单,如下图所示

csdn网站虽然是一个技术性博客,但是貌似它的反爬措施做的不那么优秀,举个例子,我在分析网页结构的过程中发现它的评论数不是通过Ajax动态渲染的,而新浪新闻做到了这一点,也许是因为新闻类的实时性要求较高而技术博客类没这个必要吧。

主要技术点

Requests库获取网页

我看到许多爬虫教程都是用的urllib2等比较过时的爬虫库来获取网页信息,一来python2马上停止支持,python2时代的urllib2的凸现出来的毛病会越来越多且无法得到官方的修复;二来无论是基于python2的ulilib2还是python3的urllib3,过程都稍显繁琐,不如requests库简明,而且urllib2/3能做的requests都能做,干嘛不用requests呢?

requests.get(url=myUrl,headers=headers).text

get()接收两个关键字参数,第一个就是我们要爬取网页的URL,第二个就是请求头,用于模拟浏览器访问服务器,不然csdn的服务器会拒绝连接,不懂的可以百度补一下计算机网络相关知识。

get()返回的是一个 requests.models.Response对象,通过它的text属性可以得到网页的源码,字符串类型,这样以后我们就能通过方便地解析网页获取我们想要的信息了。

pyqeury库解析网页

其实解析网页最直接的办法是利用 re这个库写正则表达式提取信息,优点是正则是万能的,所有的字符串提取都可以通过字符串提取,只有改变匹配的规则就行了,不过缺点是学习起来费劲(最好还是要掌握的,毕竟每个语言的匹配规则都是类似的,在java学的匹配规则照样可以用在python中,只是语法不同,API稍有差异)

第三方解析库有BeautifulSoup、lxml、pyquery等,学习这些库前最好已经掌握css选择器的一些语法规则,再学这些解析库就事半功倍了,个人感觉最好用的是pyquery库。安装pyquery需要在在命令行下输入:

pip istall pyquery

拿到网页源码后,通过

doc = pq(myPage)

得到一个 pyquery.pyquery.PyQuery对象,其中参数就是网页源码

然后可以通过

doc("aside .data-info dl").items()

来得到aside标签下class为data-info的标签下的所有dl标签,返回的仍是一个 pyquery.pyquery.PyQuery对象,如果dl的标签不止一个,我们可以通过.items()把这个对象转乘一个生成器,通过 for a in b来迭代获取每一个dl标签,同样地,迭代出来的每一个子项还是 pyquery.pyquery.PyQuery对象。

下面是pyquery常见的api

名称

功能

attr(key)

得到标签下属性key的属性值,字符串类型

parent()/children()

得到标签的父/子标签

text()

得到标签的文本

更多的api可以参考:pyqeury官方教程

另外的,假设一个 pyquery.pyquery.PyQuery对象a,通过a("li"),可以对a里的li标签再选择,所以这种选择过程可以是多重嵌套的,一个容易忘记的选择器语法是a("[b=c]"),用来选择a标签下属性b的属性值为c的所有标签。

运行结果

如下图所示,所有的功能目标已经实现

其中csdn id就是想要爬取博主的id,可以去博主的主页看

源代码

2019/01/21,代码如下:

代码最新更新在我的github:https://github.com/inspurer/PythonSpider/tree/master/csdn

同时可以关注我的csdn爬虫专栏: https://blog.csdn.net/ygdxt/column/info/30335

感谢支持!

代码语言:javascript
复制
# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_date:      2019/1/21
# file_name:        csdn
# qq_mail           2391527690@qq.com

import requests
from pyquery import PyQuery as pq

# 当前的博客列表页号
page_num = 1

account = str(input('print csdn id:'))
#account = "ygdxt"
# 首页地址
baseUrl = 'http://blog.csdn.net/' + account
# 连接页号,组成爬取的页面网址
myUrl = baseUrl + '/article/list/' + str(page_num)

headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
# 构造请求

# 访问页面
myPage = requests.get(myUrl,headers=headers).text

doc = pq(myPage)

data_info = doc("aside .data-info dl").items()
for i,item in enumerate(data_info):
    if i==0:
        print("原创:"+item.attr("title"))
    if i==1:
        print("粉丝:"+item.attr("title"))
    if i==2:
        print("喜欢:"+item.attr("title"))
    if i==3:
        print("评论:"+item.attr("title"))

grade_box = doc(".grade-box dl").items()
for i,item in enumerate(grade_box):
    if i==0:
        childitem = item("dd > a")
        print("等级:"+childitem.attr("title")[0:2])
    if i==1:
        childitem = item("dd")
        print("访问:"+childitem.attr("title"))
    if i==2:
        childitem = item("dd")
        print("积分:"+childitem.attr("title"))
    if i==3:
        print("排名:"+item.attr("title"))


# 获取每一页的信息
while True:

    # 首页地址
    baseUrl = 'http://blog.csdn.net/' + account
    # 连接页号,组成爬取的页面网址
    myUrl = baseUrl + '/article/list/' + str(page_num)
    # 构造请求
    myPage = requests.get(myUrl,headers=headers).text
    if len(myPage) < 30000:
        break

    print('-----------------------------第 %d 页---------------------------------' % (page_num,))

    doc = pq(myPage)
    articles = doc(".article-list > div").items()
    articleList = []
    for i,item in enumerate(articles):
        if i == 0:
            continue
        title = item("h4 > a").text()[2:]
        date = item("p > .date").text()
        num_item = item("p > .read-num").items()
        ariticle = [date, title]
        for j,jitem in enumerate(num_item):
            if j == 0:
                read_num = jitem.text()
                ariticle.append(read_num)
            else:
                comment_num = jitem.text()
                ariticle.append(comment_num)
        articleList.append(ariticle)
    for item in articleList:
        if(len(item)==4):
            print("%s %s %s %s"%(item[0],item[1],item[2],item[3]))
page_num = page_num + 1

最近在很忙的情况下更新了几篇文章,都是小编用心写的原创文章,但是你们既不给我好看又不转发又不赞赏,我有点疲惫啊,动动手指点击好看转发,你不花一分钱,但却是对我的极大鼓励,多谢了!

系列教程预告

机器学习模式识别之环境搭建、数据集训练&测试、应用识别。

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

本文分享自 月小水长 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 爬取目标
  • 思路分析
  • 主要技术点
    • Requests库获取网页
      • pyqeury库解析网页
      • 运行结果
      • 源代码
      相关产品与服务
      云开发 CLI 工具
      云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档