本文章是下文連接的學習筆記: 一小時入門python3網絡爬蟲
原文筆記是在winows下進行的,本文是在ubuntu下進行的全部操做.
爬蟲的大概思路其實就兩點:html
- 獲取網頁的HTML信息
- 解析HTML信息,提取咱們真正須要的內容
chrome:F12python
網絡爬蟲根據提供的URL信息,獲取網頁的HTML信息.
在Python\3中使用request和urllib.request來獲取網頁的具體信息.git
- urllib庫Python內置,無需額外安裝
- request是第三方庫,須要額外安裝 request庫的地址
sudo apt-get install python-requests
/* 構造一個請求,支撐如下各方法的基礎方法 */ requests.request() /*獲取HTML網頁的主要方法,對應HTTP的GET*/ requests.get() /*獲取HTML網頁頭信息的方法,對應於HTTP的HEAD*/ requests.head() /*向HTML網頁提交POST請求的方法,對應於HTTP的POST*/ requests.post() /*向HTML網頁提交PUT請求的方法,對應於HTTP的PUT*/ requests.put() /*向HTML提交局部修改請求,對應於HTTP的PATCH*/ requests.patch() /*向HTML頁面提交刪除請求,對應於HTTP的DELETE*/ requests.delete()
requests庫的使用教程
get請求的意思,顧名思義,就是從服務器獲取數據信息.下面是一個例子:github
#-*- coding:UTF-8 -*- 2 import requests 3 if __name__ == '__main__': 4 target = 'http://gitbook.cn/' 5 req = requests.get(url=target) //req中保存了咱們獲取到信息 6 print(req.text)
下面是執行上面的程序後抓取到的HTML信息: 正則表達式
目標網站:http://www.biqukan.com/
這是個小說網站.此次的目標是爬去並保存一本名爲"意念永恆"的小說.chrome
爬取"一念永恆"第一章的內容
將前面寫的代碼稍做修改運行就能夠了,以下:ubuntu
# -*- coding:UTF-8 -*- import requests if __name__ == '__main__': target = 'http://www.biqukan.com/1_1094/5403177.html' req = requests.get(url=target) print(req.text)
運行代碼,會發現獲得的是一堆帶有各類HTML標籤的小說內容.接下來的目標就是講小說的內容提取出來,過濾掉這些沒用的HTML標籤.服務器
提取咱們真正須要的內容有不少方法,例如用正則表達式,Xpath,Beautiful Soup等.這裏使用Beautifu Soup.
Beautiful Soup是一個第三方庫,這裏是中文學習文檔
beautiful soup 4的安裝方法:網絡
sudo apt-get install python-bs4
檢驗beautiful soup是否成功的方法:app
from bs4 import BeautifulSoup
觀察能夠看到,div\標籤中存放了小說的正文內容,因此如今的目標就是把div中的內容提取出來.
這裏div設置了兩個屬性class和id.id是div的惟一標識,class規定元素的一個或多個類名.
提取小說正文內容的代碼以下:
# -*- coding:utf-8 -*- import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'http://www.biqukan.com/1_1094/5403177.html' req = requests.get(url=target) html = req.text bf = BeautifulSoup(html,'lxml') ##使用find_all方法,獲取html信息中全部class屬性爲showtxt的div標籤 ##find_all的第一個參數是獲取的標籤名,第二個參數class_是標籤屬性 ##class在Python中是關鍵字,因此用class_標識class屬性,,避免衝突 texts = bf.find_all('div',class_ = 'showtxt') ##decoude()是爲了將texts轉變成中文,若是不用這個方法,輸出的內容就是一堆編碼 print(texts[0].decode())
從圖片中能夠看出,此時的內容中還有一些其餘的HTML標籤,好比<br>
接下來就是要把這些不須要的字符去除,還有一些不須要的空格也刪除.代碼以下:
1 # -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 target = 'http://www.biqukan.com/1_1094/5403177.html' 7 req = requests.get(url=target) 8 html = req.text 9 bf = BeautifulSoup(html,'lxml') 10 ##使用find_all方法,獲取html信息中全部class屬性爲showtxt的div標籤 11 ##find_all的第一個參數是獲取的標籤名,第二個參數class_是標籤屬性 12 ##class在Python中是關鍵字,因此用class_標識class屬性,,避免衝突 13 texts = bf.find_all('div',class_ = 'showtxt') 14 ##decoude()是爲了將texts轉變成中文,若是不用這個方法,輸出的內容就是一堆編碼 15 print(texts[0].text.replace('\xa0'*8,'\n\n'))
運行代碼後,抓取效果以下:
在HTML中用" "表示空格(記得後面加;號).上面代碼的最後一行的意思就是:
去掉文中的8個空格符號,並能用回車代替.
到目前爲止,咱們已經能夠抓取到小說一章的內容,而且進行了分段顯示.下一個目標就是要把整個小說都下載下來.
經過審查元素,咱們能夠看到,目標小說的全部章節標題都存在於<div class="listmain">標籤下.
具體章節又分別存在於<div>子標籤中的<dd><a></a></dd>標籤中. html中,標籤<a></a>用來存放超連接,連接地址存在於屬性href中.
接下來,就是先抓取小說的目錄列表,代碼以下:
1 # -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 target = 'http://www.biqukan.com/1_1094/' 7 req = requests.get(url=target) 8 html = req.text 9 div_bf = BeautifulSoup(html) 10 div = div_bf.find_all('div',class_="listmain") 11 print(div[0])
抓取結果以下:
接下來,就是匹配抓取到的每個<a></a>標籤,並提取章節名和章節文章.例如,取第一章,標籤內容以下:
<a href="/1_1094/5403177.html">第一章 他叫白小純</a>
對BeautifulSoup返回的匹配結果a,使用a.get("href")方法,就能獲取href的屬性值,使用a.string就能獲取章節名,代碼以下:
1 -*- coding:utf-8 -*- 2 import requests 3 from bs4 import BeautifulSoup 4 5 if __name__ == '__main__': 6 server = 'http://www.biqukan.com' 7 target = 'http://www.biqukan.com/1_1094/' 8 req = requests.get(url=target) 9 html = req.text 10 div_bf = BeautifulSoup(html) 11 div = div_bf.find_all('div',class_="listmain") 12 a_bf = BeautifulSoup(str(div[0])) 13 a=a_bf.find_all('a') 14 for each in a: 15 print(each.string,server+each.get('href'))
代碼執行結果:
如今每一個章節的章節名,章節連接都有了.接下來就是整合代碼,將得到的內容寫入文本文件存儲就行了,代碼以下:
#-*-coding:utf-8-*- 2 from bs4 import BeautifulSoup 3 import requests,sys 4 5 class downloader(object): 6 def __init__(self): 7 self.server = 'http://www.biqukan.com/' 8 self.target = 'http://www.biqukan.com/1_1094/' 9 self.names = [] #存放章節名 10 self.urls = [] #存放章節連接 11 self.nums = 0 #章節數 12 13 #獲取下載地址 14 def get_download_url(self): 15 req = requests.get(url = self.target) 16 html = req.text 17 div_bf = BeautifulSoup(html) 18 div = div_bf.find_all('div',class_='listmain') 19 a_bf = BeautifulSoup(str(div[0])) 20 a = a_bf.find_all('a') 21 self.nums = len(a[15:]) 22 for each in a[15:]: 23 self.names.append(each.string) 24 self.urls.append(self.server+each.get('href')) 25 26 #獲取章節內容 27 def get_contents(self,target): 28 req = requests.get(url =target) 29 html = req.text 30 bf = BeautifulSoup(html) 31 texts = bf.find_all('div',class_='showtxt') 32 texts = texts[0].text.replace('\xa0'*8,'\n\n') 33 return texts 34 35 #將抓取的文章內容寫入文件 36 def writer(self,name,path,text): 37 write_flag = True 38 with open(path,'a',encoding='utf-8') as f: 39 f.write(name+'\n') 40 f.writelines(text) 41 f.write('\n\n') 42 43 #主函數 44 if __name__ == "__main__": 45 dl = downloader() 46 dl.get_download_url() 47 print('<一年永恆>開始下載:') 48 for i in range(dl.nums): 49 dl.writer(dl.names[i],'一念永恆.txt',dl.get_contents(dl.urls[i])) 50 sys.stdout.write(" 已下載:%.3f%%"% float(i/dl.nums)+'\r') 51 sys.stdout.flush() 52 print('<一念永恆>下載完成')