Python之簡單爬蟲

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模塊:

  1. 運行cmd
  2. cd C:\Users\Administrator\AppData\Local\Programs\Python\Python36\Scripts
  3. dir
  4. pip install beautifulsoup4

測試:

2.5.2  Beautiful Soup語法

  • 根據HTML網頁,建立一個BeautifulSoup對象
  • 搜索節點(find_all、find兩種方法)(同時,能夠按照節點名稱、節點屬性、節點文字等進行搜索)
  • 最後訪問節點(名稱、屬性、文字等)

例如:

1 <a href="123.html" class='article_link'> Python </a>
  1. 若按照節點名稱:a
  2. 若按照節點屬性:href='123.html'或'class=article_link'
  3. 若按照節點文字: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

3.3  運行結果

相關文章
相關標籤/搜索