忽然闲来无事想要爬取csdn博客,顺便温习下相关技术点。css
爬取目标
以个人csdn主页为例爬取的主要的数据已经在上用红线图标出来了,主要可分为两部分html
全部博客的八个统计数据,原创的博客数、你的粉丝数、博客得到的赞、博客的评论数、博客等级、访问量、积分和排名java
每篇博客的具体信息,如标题、发布时间、阅读数、评论数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源创计划”,欢迎正在阅读的你也加入,一块儿分享。