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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索