忽然閒來無事想要爬取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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。