參考資料html
代碼實現(一): 用Python抓取指定頁面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部分. 首先看到的是一句話介紹這個庫是幹什麼用的:web
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的網頁, 則代碼以下cookie
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(), 一樣經過官方文檔學習一下他是幹什麼的. 經過查看網絡
大概知道他是把一個通俗的字符串, 轉化爲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 界大名鼎鼎的一個網絡庫, 其設計哲學是爲人類而設計, 因此他提供的功能都很是的人性化. 他的方便對我而言主要有兩大點:
Requests 的方便之處不止這兩點, 還提供了諸如標準登陸接口之類的功能, 咱們暫時用不上.
總而言之, 對於使用過 urllib 的咱們來講, 用 requests 會感受咱們以前生活在石器時代. 第三方庫的強大就在於這裏, 這也是 Python 這麼火的重要緣由.
BeautifulSoup Module
BeautifulSoup 大大方便了咱們對抓取的 HTML 數據的解析, 能夠用tag, class, id來定位咱們想要的東西, 能夠直接提取出正文信息, 能夠全文搜索, 一樣也支持正則表達式, 至關給力.
小試牛刀
咱們隨便抓取一個頁面, 而後用 soup 來解析一下試試他的威力:
1 >>> import requests 2 >>> from bs4 import BeautifulSoup 3 >>> response = requests.get("http://jecvay.com") 4 >>> soup = BeautifulSoup(response.text) 5 6 >>> print(soup.title.text) 7 Jecvay Notes - Good luck & Have fun 8 9 >>> print(soup.body.text) 10 改版策略: 技術博客的真正索引 11 12 上週, 我換掉了我博客的主題, 使用 BootStrap 框架本身寫了一個. 在本身動手寫博客主題以前, 13 我時常時不時到後臺主題商店去翻一翻, 想要發現更好看的主題. 挑選有兩種: 14 在一大堆展現面前, 快速瀏覽, 看到亮眼的就仔細看一看是否滿意; 15 本身想好一個目標, 而後用篩選器(或者人肉)篩選出來. 16 閱讀全文 >> (...省略若干) 17 18 >>> for x in soup.findAll("a"): 19 ... print(x['href']) 20 ... 21 http://jecvay.com/2015/02/the-real-index-of-tech-blog.html 22 http://jecvay.com/2015/02/the-real-index-of-tech-blog.html 23 http://jecvay.com/2015/01/wordpress-super-cache.html 24 http://jecvay.com/2015/01/learning-vps-3.html 25 http://jecvay.com/2015/01/nobot-anti-webspider.html 26 http://jecvay.com/2015/01/learning-vps-2.html 27 http://jecvay.com/2014/12/learning-vps-1.html 28 http://jecvay.com/2014/11/what-is-min-cut.html 29 http://jecvay.com/2014/11/compiler-makes-fast-build.html 30 /about-me 31 /archive
咱們十分輕鬆的得到了全文內容以及全部連接.
在上一篇文章中, 我嘗試使用 urllib 和 re 獲取了知乎登陸頁面的 _xsrf 參數, 此次咱們經過這兩個新的模塊再試一次.
打開瀏覽器隱身模式, 打開知乎網, 來到登陸界面, 查看源代碼, 搜索 xsrf 字樣, 獲得以下一行:
<input type="hidden" name="_xsrf" value="d4ff8d988193442a774bd0ccff336101"/>
因而咱們只要兩行代碼就能搞定:
1 >>> soup = BeautifulSoup(requests.get("http://www.zhihu.com").text) 2 >>> print(soup.find("input", {"name": "_xsrf"})['value']) 3 d4ff8d18b293442a764bd0ccff333601
第三方庫就是這麼好用!