requests+pyquery爬取csdn博客信息

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

爬取目标

以个人csdn主页为例爬取的主要的数据已经在上用红线图标出来了,主要可分为两部分html

  1. 全部博客的八个统计数据,原创的博客数、你的粉丝数、博客得到的赞、博客的评论数、博客等级、访问量、积分和排名java

  2. 每篇博客的具体信息,如标题、发布时间、阅读数、评论数python

思路分析

Google Chrome浏览器F12开发者工具查看网页结构,比较简单,以下图所示csdn网站虽然是一个技术性博客,可是貌似它的反爬措施作的不那么优秀,举个例子,我在分析网页结构的过程当中发现它的评论数不是经过Ajax动态渲染的,而新浪新闻作到了这一点,也许是由于新闻类的实时性要求较高而技术博客类没这个必要吧。git

主要技术点

Requests库获取网页

我看到许多爬虫教程都是用的urllib2等比较过期的爬虫库来获取网页信息,一来python2立刻中止支持,python2时代的urllib2的凸现出来的毛病会愈来愈多且没法获得官方的修复;二来不管是基于python2的ulilib2仍是python3的urllib3,过程都稍显繁琐,不如requests库简明,并且urllib2/3能作的requests都能作,干吗不用requests呢?github

requests.get(url=myUrl,headers=headers).text正则表达式

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

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

感谢支持!

  
    
  
  
   
   
   
   













# -*- coding: utf-8 -*-# author:           inspurer(月小水长)# pc_type           lenovo# create_date:      2019/1/21# file_name:        csdn# qq_mail           2391527690@qq.comimport requestsfrom pyquery import PyQuery as pq# 当前的博客列表页号page_num = 1account = 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).textdoc = 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


悄悄话

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


系列教程预告

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

本文分享自微信公众号 - 月小水长(inspurer)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索