大家好,上次我們實驗了爬取了糗事百科的段子,那麼這次我們來嘗試一下爬取百度貼吧的文章。與上一篇不同的是,這次我們需要用到檔案的相關操作。
本篇目标
1.對百度貼吧的任意文章進行抓取
2.指定是否隻抓取樓主發帖内容
3.将抓取到的内容分析并儲存到檔案
1.URL格式的确定
首先,我們先觀察一下百度貼吧的任意一個文章。
http:// 代表資源傳輸使用http協定
tieba.baidu.com 是百度的二級域名,指向百度貼吧的伺服器。
/p/3138733512 是伺服器某個資源,即這個文章的位址定位符
see_lz和pn是該URL的兩個參數,分别代表了隻看樓主和文章頁碼,等于1表示該條件為真
是以我們可以把URL分為兩部分,一部分為基礎部分,一部分為參數部分。
2.頁面的抓取
熟悉了URL的格式,那就讓我們用urllib2庫來試着抓取頁面内容吧。上一篇糗事百科我們最後改成了面向對象的編碼方式,這次我們直接嘗試一下,定義一個類名叫BDTB(百度貼吧),一個初始化方法,一個擷取頁面的方法。
其中,有些文章我們想指定給程式是否要隻看樓主,是以我們把隻看樓主的參數初始化放在類的初始化上,即init方法。另外,擷取頁面的方法我們需要知道一個參數就是文章頁碼,是以這個參數的指定我們放在該方法中。
綜上,我們初步建構出基礎代碼如下:
1 #-*- coding:utf-8 -*-
2 importurllib3 importurllib24 importre5 import sys #1
6 importthread7 importtime8
9 #百度貼吧爬蟲類
10 #http://tieba.baidu.com/p/3138733512?see_lz=1&pn=1
11 classBDTB(object):12 """docstring for QSBK"""
13 #初始化,傳入基位址,是否隻看樓主的參數
14 def __init__(self,baseURL,seeLZ):15 self.baseURL =baseURL16 self.seeLZ = '?see_lz='+str(seeLZ)17
18 #傳入頁碼,擷取該頁文章的代碼
19 defgetPage(self,pageNum):20 try:21 url = self.baseURL + self.seeLZ + '&pn=' +str(pageNum)22 request =urllib2.Request(url)23 response =urllib2.urlopen(request)24 #pageCode = response.read().decode('utf-8')
25 print url + '\n'
26 printresponse.read()27 returnresponse28 excepturllib2.URLError, e:29 if hasattr(e,"code"):30 printe.code31 if hasattr(e,"reason"):32 printe.reason33 returnNone34
35 if __name__ == '__main__':36 baseURL = 'http://tieba.baidu.com/p/3138733512'
37 bdtb = BDTB(baseURL,1)38 bdtb.getPage(1)
3.提取相關資訊
1)提取文章标題
首先,讓我們提取文章的标題。
在浏覽器中審查元素,或者按F12,檢視頁面源代碼,我們找到标題所在的代碼段,可以發現這個标題的HTML代碼是
#純原創我心中的NBA2014-2015賽季現役50大
是以我們想提取
标簽中的内容,同時還要指定這個class确定唯一,因為h1标簽實在太多啦。
正規表達式如下
(.*?)
是以,我們增加一個擷取頁面标題的方法
1 defgetTitle(self):2 page = self.getPage(1)3 pattern = re.compile('
.*?(.*?)',re.S)4 result =re.search(pattern,page)5 ifresult:6 #print result.group(1) #測試輸出
7 return result.group(1).strip()8 else:9 return None
3)提取正文内容
審查元素,我們可以看到百度貼吧每一層樓的主要内容都在
标簽裡面,是以我們可以寫如下的正規表達式
(.*?) ',re.S)4 items =re.findall(pattern,page)5 for item initems:6 print item
真是醉了,還有一大片換行符和圖檔符,好口怕!既然這樣,我們就要對這些文本進行處理,把各種各樣複雜的标簽給它剔除掉,還原精華内容,把文本處理寫成一個方法也可以,不過為了實作更好的代碼架構和代碼重用,我們可以考慮把标簽等的處理寫作一個類。
那我們就叫它Tool(工具類吧),裡面定義了一個方法,叫replace,是替換各種标簽的。在類中定義了幾個正規表達式,主要利用了re.sub方法對文本進行比對後然後替換。具體的思路已經寫到注釋中,大家可以看一下這個類