python3網絡爬蟲筆記


參考資料

代碼實現(一): 用Python抓取指定頁面

1 #!/usr/bin/env python
2 #encoding:UTF-8
3 import urllib.request
4  
5 url = "http://www.baidu.com"
6 data = urllib.request.urlopen(url).read()
7 data = data.decode('UTF-8')
8 print(data)

      urllib.request是一個庫, 隸屬urllib. 點此打開官方相關文檔. 官方文檔應該怎么使用呢? 首先點剛剛提到的這個鏈接進去的頁面有urllib的幾個子庫, 我們暫時用到了request, 所以我們先看urllib.request部分. 首先看到的是一句話介紹這個庫是干什么用的:

      The urllib.request module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.

     然后把我們代碼中用到的urlopen()函數部分閱讀完.

     urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False)

      重點部分是返回值, 這個函數返回一個 http.client.HTTPResponse 對象, 這個對象又有各種方法, 比如我們用到的read()方法, 這些方法都可以根據官方文檔的鏈接鏈過去. 根據官方文檔所寫, 我用控制台運行完畢上面這個程序后, 又繼續運行如下代碼, 以更熟悉這些亂七八糟的方法是干什么的。

>>> import urllib.request
>>> a = urllib.request.urlopen('http://10.54.0.2/OAapp/WebObjects/OAapp.woa')
>>> type(a)
<class 'http.client.HTTPResponse'>
>>> a.geturl()
'http://10.54.0.2/OAapp/WebObjects/OAapp.woa'
>>> a.info()
<http.client.HTTPMessage object at 0x7f390a3d4780>
>>> a.getcode()
200

 如果要抓取百度上面搜索關鍵詞為Jecvay Notes的網頁, 則代碼如下

 1 #!/usr/bin/env python
 2 #encoding:UTF-8
 3 import urllib
 4 import urllib.request
 5 
 6 data={}
 7 data['word']='Jecvay Notes'
 8 
 9 url_values=urllib.parse.urlencode(data)
10 url="http://www.baidu.com/s?"
11 full_url=url+url_values
12 
13 data=urllib.request.urlopen(full_url).read()
14 data=data.decode('UTF-8')
15 print(data)

      data是一個字典, 然后通過urllib.parse.urlencode()來將data轉換為 'word=Jecvay+Notes'的字符串, 最后和url合並為full_url, 其余和上面那個最簡單的例子相同. 關於urlencode(), 同樣通過官方文檔學習一下他是干什么的. 通過查看

  1. urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None)
  2. urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)

     大概知道他是把一個通俗的字符串, 轉化為url格式的字符串。

Python的隊列

     在爬蟲程序中, 用到了廣度優先搜索(BFS)算法. 這個算法用到的數據結構就是隊列.

      Python的List功能已經足夠完成隊列的功能, 可以用 append() 來向隊尾添加元素, 可以用類似數組的方式來獲取隊首元素, 可以用 pop(0) 來彈出隊首元素. 但是List用來完成隊列功能其實是低效率的, 因為List在隊首使用 pop(0) 和 insert() 都是效率比較低的, Python官方建議使用collection.deque來高效的完成隊列任務.

 1 #!/usr/bin/env python
 2 #encoding:UTF-8
 3 from collections import deque
 4 queue = deque(["Eric", "John", "Michael"])
 5 queue.append("Terry")           # Terry 入隊
 6 print(queue)
 7 queue.append("Graham")          # Graham 入隊
 8 print(queue)
 9 queue.popleft()                 # 隊首元素出隊
10 print(queue)
11 #輸出: 'Eric'
12 queue.popleft()                 # 隊首元素出隊
13 #輸出: 'John'
14 print(queue)                    # 隊列中剩下的元素

 

Python的集合

      在爬蟲程序中, 為了不重復爬那些已經爬過的網站, 我們需要把爬過的頁面的url放進集合中, 在每一次要爬某一個url之前, 先看看集合里面是否已經存在. 如果已經存在, 我們就跳過這個url; 如果不存在, 我們先把url放入集合中, 然后再去爬這個頁面。

      Python提供了set這種數據結構. set是一種無序的, 不包含重復元素的結構. 一般用來測試是否已經包含了某元素, 或者用來對眾多元素們去重. 與數學中的集合論同樣, 他支持的運算有交, 並, 差, 對稱差.

創建一個set可以用 set() 函數或者花括號 {} . 但是創建一個空集是不能使用一個花括號的, 只能用 set() 函數. 因為一個空的花括號創建的是一個字典數據結構. 以下同樣是Python官網提供的示例。

 1 >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
 2 >>> print(basket)                      # 這里演示的是去重功能
 3 {'orange', 'banana', 'pear', 'apple'}
 4 >>> 'orange' in basket                 # 快速判斷元素是否在集合內
 5 True
 6 >>> 'crabgrass' in basket
 7 False
 8  
 9 >>> # 下面展示兩個集合間的運算.
10 ...
11 >>> a = set('abracadabra')
12 >>> b = set('alacazam')
13 >>> a                                  
14 {'a', 'r', 'b', 'c', 'd'}
15 >>> a - b                              # 集合a中包含元素
16 {'r', 'd', 'b'}
17 >>> a | b                              # 集合a或b中包含的所有元素
18 {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
19 >>> a & b                              # 集合a和b中都包含了的元素
20 {'a', 'c'}
21 >>> a ^ b                              # 不同時包含於a和b的元素
22 {'r', 'd', 'b', 'm', 'z', 'l'}

    其實我們只是用到其中的快速判斷元素是否在集合內的功能, 以及集合的並運算。

Requests Module

Requests 是 Python 界大名鼎鼎的一個網絡庫, 其設計哲學是為人類而設計, 所以他提供的功能都非常的人性化. 他的方便對我而言主要有兩大點:

  • 對 GET 和 POST 方法的封裝做的很好, 自動處理了編碼等問題;
  • 默認開啟了 Cookies 處理, 在處理需要登錄的問題上面非常方便.

Requests 的方便之處不止這兩點, 還提供了諸如標准登錄接口之類的功能, 我們暫時用不上.

總而言之, 對於使用過 urllib 的我們來說, 用 requests 會感覺我們之前生活在石器時代. 第三方庫的強大就在於這里, 這也是 Python 這么火的重要原因.

BeautifulSoup Module

BeautifulSoup 大大方便了我們對抓取的 HTML 數據的解析, 可以用tag, class, id來定位我們想要的東西, 可以直接提取出正文信息, 可以全文搜索, 同樣也支持正則表達式, 相當給力.

小試牛刀

我們隨便抓取一個頁面, 然后用 soup 來解析一下試試他的威力:

      我們十分輕松的獲得了全文內容以及所有鏈接.

重訪知乎

     在上一篇文章中, 我嘗試使用 urllib 和 re 獲取了知乎登錄頁面的 _xsrf 參數, 這次我們通過這兩個新的模塊再試一次.

打開瀏覽器隱身模式, 打開知乎網, 來到登錄界面, 查看源代碼, 搜索 xsrf 字樣, 得到如下一行:

    於是我們只要兩行代碼就能搞定:

    第三方庫就是這么好用!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM