1 爬蟲是什麼?
1.1 爬蟲定義
爬蟲:一段自動抓取互聯網信息的程序。html
爬蟲能夠從一個URL出發,訪問它所關聯的全部URL,而且從每一個頁面上提取出有價值的數據。node
1.2 爬蟲技術的價值
價值:互聯網數據,爲我所用!python
2 Python簡單爬蟲構架
2.1 三大模塊
爬蟲調度端:URL管理器、網頁下載器、網頁解析器。正則表達式
URL管理器:保存已爬過的網頁URL和待爬網頁的URL,待爬網頁的URL將傳遞給網頁下載器。redis
網頁下載器:網頁下載器會把URL管理器傳遞過來的URL網頁下載下來,存儲成一個字符串,這個字符串將傳送給網頁解析器進行解析。數據庫
網頁解析器:一方面,將從該網頁提取有價值的數據;另外一方面,該網頁也會存在一些URL,會把這個URL補充進URL管理器。緩存
2.2 運行流程
2.3 URL管理器
URL管理器:管理待爬取URL集合和已抓取URL集合。cookie
之因此用URL管理器,是爲了防止抓取、防止循環抓取。工具
URL管理器:測試
- 添加新URL到待爬取集合中。
- 判斷待添加阞是否在容器中。
- 獲取待爬取URL。
- 判斷是否還有待爬取URL。
- 將URL從待爬取移動到已爬取。
實現方式:
- 內存(Python內存:set())
- 關係數據庫(MySQL)
- 緩存數據庫(redistribute:set)
2.4 網頁下載器
2.4.1 簡介
網頁下載器:將互聯網上URL對應的網頁下載到本地的工具。
實現方法:網頁下載器訪問該URL,將對應的HTML文件保存到本地或內存字符串中。
Python網頁下載器:
- urllib2(Python官方基礎模塊,只能Python2使用,Python3須要使用urllib.request)
- requests(第三方包更強大)
2.4.2 urllib2下載網頁方法1:最簡潔的方法
根據URL,用urllib2.urlopen(url)方法。
1 import urllib2 2 #直接請求 3 response = urllib2.urlopen('http://www.baidu.com') 4 #獲取狀態碼,若是是200表示獲取成功 5 print response.getcode() 6 #讀取內容 7 cont = response.read()
2.4.3 urllib2下載網頁方法2:添加data、http header
根據url、data、header,建立urllib2.Request對象,用urllib2.urlopen(request)方法。
1 import urllib2 2 #建立Request對象 3 request = urllib2.Request(url) 4 #添加數據 5 request.add_data('a','1') 6 #添加http的header 7 request .add_header('User-Agent','Mozilla/5.0') 8 #發送請求獲取結果 9 response = urllib2.urlopen(request)
2.4.4 urllib2下載網頁方法3:添加特殊情景的處理器
有些網頁須要登錄或代理服務才能訪問,因此須要HTTPCookieProcessor、ProxyHandler、HTTPSHandler、HTTPRedirectHandler。
1 import urllib2,cookielib 2 #建立cookie容器 3 cj = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 4 #給urllib2安裝opener 5 urllib2.install_opener(opener) 6 #使用帶有cookie的urllib2訪問網頁 7 response = urllib2.urlopen("http://www.baidu.com/")
2.4.5 三種方法程序實例
1 #coding:utf-8 2 import urllib.request 3 import http.cookiejar 4 5 url = "http://www.baidu.com" 6 7 print('第一種方法') 8 response1 = urllib.request.urlopen(url) 9 print(response1.getcode()) 10 print(len(response1.read())) 11 12 print('第二種方法') 13 request = urllib.request.Request(url) 14 request.add_header("user-agent","Mozilla/5.0") 15 response2 = urllib.request.urlopen(request) 16 print(response2.getcode()) 17 print(len(response2.read())) 18 19 print('第三種方法') 20 cj = http.cookiejar.CookieJar() 21 opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) 22 urllib.request.install_opener(opener) 23 response3 = urllib.request.urlopen(url) 24 print(response3.getcode()) 25 print(cj) 26 print(len(response3.read()))
運行結果:
注意:
- Python3.x中urllib庫和urilib2庫合併成了urllib庫。其中,urllib2.urlopen()變成了urllib.request.urlopen(), urllib2.Request()變成了urllib.request.Request()。
- Python3.x中沒有cookiejar庫,替換爲http.cookiejar。
- 連接1
- 連接2
- 連接3
2.5 網頁解釋器
2.5.1 簡介
網頁解釋器:從網頁中提取出有價值數據的工具。
Python網頁解釋器:
- 正則表達式(模糊查詢)
- html.parser(Python自帶)(結構化查詢)
- Beautiful Soup(第三方庫,很強大)(結構化查詢)
- lxml(結構化查詢)
結構化查詢:
安裝Beautiful Soup模塊:
- 運行cmd
- cd C:\Users\Administrator\AppData\Local\Programs\Python\Python36\Scripts
- dir
- pip install beautifulsoup4
測試:
2.5.2 Beautiful Soup語法
- 根據HTML網頁,建立一個BeautifulSoup對象
- 搜索節點(find_all、find兩種方法)(同時,能夠按照節點名稱、節點屬性、節點文字等進行搜索)
- 最後訪問節點(名稱、屬性、文字等)
例如:
1 <a href="123.html" class='article_link'> Python </a>
- 若按照節點名稱:a
- 若按照節點屬性:href='123.html'或'class=article_link'
- 若按照節點文字:Python
建立一個BeautifulSoup對象:
1 from bs4 import BeautifulSoup 2 #根據HTML網頁字符串建立BeautifulSoup對象 3 soup = BeautifulSoup( 4 #HTML文檔字符串 5 html_doc, 6 #HTML解析器 7 'html.parser', 8 #HTML文檔的編碼 9 from_encoding='utf-8' 10 )
搜索節點:
1 #方法:find_all(name,sttrs,string) 2 #查找全部標籤爲a的節點 3 soup.find_all('a') 4 #查找全部標籤爲a,連接符合/view/123.htm形式的節點 5 soup.find_all('a',href='/view/123.htm') 6 soup.find_all('a',href=re.compile(r'/view/\d+\.htm')) 7 #查找全部標籤爲div,class爲abc,文字爲Python的節點 8 soup.find_all('div',class_='abc',string='Python')
訪問節點信息:
1 #獲得節點<a href='1.html'>Python</a> 2 #獲取查找到的節點的標籤名稱 3 node.name 4 #獲取查找到的a節點的href屬性 5 node['href'] 6 #獲取查找到的a節點的連接文字 7 node.get_text()
2.5.3 BeautifulSoup實例
1 from bs4 import BeautifulSoup 2 import re 3 4 html_doc = """ 5 <html><head><title>The Dormouse's story</title></head> 6 <body> 7 <p class="title"><b>The Dormouse's story</b></p> 8 <p class="story">Once upon a time there were three little sisters; and their names were 9 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, 10 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and 11 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a> 12 and they lived at the bottom of a well.</p> 13 <p class="story">...</p> 14 """ 15 16 #soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf-8') 17 #python3 缺省的編碼是unicode, 再在from_encoding設置爲utf8, 會被忽視掉,故去掉【from_encoding="utf-8"】 18 soup = BeautifulSoup(html_doc, 'html.parser') 19 20 print('獲取全部連接') 21 links = soup.find_all('a') 22 for link in links: 23 print(link.name, link['href'], link.get_text()) 24 25 print('獲取Lacie連接') 26 linknode = soup.find_all('a', href='http://example.com/lacie') 27 for link in linknode: 28 print(link.name, link['href'], link.get_text()) 29 30 print('正則匹配') 31 #引入正則表達式 32 linknode = soup.find_all('a', href=re.compile(r'ill')) 33 for link in linknode: 34 print(link.name, link['href'], link.get_text()) 35 36 print('獲取P') 37 pnode = soup.find_all('p', class_='title') 38 for link in pnode: 39 print(link.name, link.get_text())
運行結果:
3 爬取百度百科100個頁面的數據(標題和簡介)
肯定目標->分析目標->編寫代碼->執行爬蟲
3.1 分析目標
- URL格式
- 數據格式
- 網頁編碼(右鍵,審查元素)
- 目標:百度百科Python詞條相關詞條網頁(標題和簡介)
- 入口頁:http://baike.baidu.com/item/Python(可能隨着更新,此URL也會更新)
- URL格式
- 數據格式
3.2 程序
見附件:https://pan.baidu.com/s/1kW2oXD1