百度關鍵字批量提取url
- 如何寫合適的正則表達式以從html中提取鏈接
- 如何利用urllib提取鏈接
- 如何將提取出來的鏈接去重復
- 如何用提取出來的鏈接得到真實鏈接
- 如何將得到的鏈接合適的輸出並保存
- 在提取真實鏈接的過程中如何處理時常發生的異常
一、正則表達式
通過利用瀏覽器進行百度搜索,查看獲得的搜索結果頁面的源碼,可以發現所有的下需要的鏈接前面都有http://www.baidu.com/link?url=這樣的特徵,所以可以利用此字符串寫正則表達式去匹配鏈接。
http://www.baidu.com/link?url=lOVpypUMi-s0tEaa_RkhE9yAbJBN8wleuMEv_Pay6cVvmeUBnlwWt6Xo6ci05sMw 訪問這個鏈接之後,會跳轉到http://top.baidu.com/?fr=tph_right 上。所以前者就是我們初步要找的鏈接。
=號後面是由字母數字下劃線包括段橫組成的字符串,用正則表達式可以寫作[a-zA-Z0-9_-]+。其中a-z表示所有小寫字母,A-Z 表示所有大寫字母,0-9表示數字,加號表示匹配一個或多個。所以總的正則表達式可以寫作http://www.baidu.com/link?url=[a-zA-Z0-9_-]+。 但是在python中.?/這些符號是特殊符號,需要在其前面加上轉意符\。所以整個正則表達式寫作http://www.baidu.com/link\?url=[a-zA-Z0-9_-]+
在python中使用的話,可以通過導入re模塊使用
import re
p = r"http://www\.baidu\.com/link\?url=[a-zA-Z0-9_-]+"
pa = re.compile(p)
#p後面的r“”表示p爲後面字符串的原始字符串,這個r加不加都可以
由於我們後面需要多次利用正則表達式匹配,所以這裏利用re.compile將正則表達式編譯爲正則表達式對象,以在後面使用過程中加快匹配效率。所以pa爲一個正則表達式對象,可以使用正則表達式方法。
如何利用urllib提取鏈接
python2中的urllib與python3中大有不同,這裏只做python3的介紹
for i in range(max_page):
r_url = "http://www.baidu.com/s?wd="+keyword+"&pn="+str(i)+"0"
req = request.Request(r_url,headers=head)
htm = urllib.request.urlopen(req).read()
html = htm.decode('UTF-8')
begin_urls = pa.findall(html)
ss_urls = sorted(set(begin_urls),key = begin_urls.index)
s_urls += ss_urls
- python3中使用urllib庫進行獲取網絡資源。
- 第一行使用關鍵字及頁數作爲變量構造url*然後就是request.Request這個方法是將請求頭編碼。由於利用python庫訪問鏈接時默認的useragent是python的(具體是什麼我也忘了,總之跟實際瀏覽器的useragent不一樣)而有些網站限制了這類agent的訪問,所以這裏用真是環境的瀏覽器的useragent僞造。head
= {‘User-Agent’:’Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101
Safari/537.36’}。上面代碼中request.Request(url,header=head)執行過後,我們的程序v發出去的請求頭裏面便是head中的agent了。 - 而htm=urllib.request.urlopen(url).read()直接獲取鏈接資源,返回的是一個byte類型的數據類(也即爲經編碼的數據),注意此時還不能直接對htm進行匹配,必須先對其編碼將其合適的轉換之後才能匹配
- 由於是中文網站所以用UTF-8編碼html =htm.decode(‘UTF-8’)。此時html就是一個文本對象了,可以對其使用文本對象的方法。然後利用re模塊中的findall進行匹配(因爲pa已經是個正則表達式對象了,所以可以直接對其利用正則表達式方法findall)。至此已經提取鏈接到begin_urls列表了。
如何將提取出來的鏈接去重復
經檢查,獲得的begin_urls列表中確實有重復項,所以我沒爲了提高程序v效率必須v進行去重。這裏利用到了集合的特性,集合是一組無序,兩兩不等的。所以利用set(begin_urls)可以得到一個無重復項的集合,再利用sorted排序v函數進行排序。sorted(list,key)這裏的key參數採用剛剛去重復之前begin_urls中的順序(begin_urls.index)對新的去衝後的序列進行排序。所以輸出的ss_url列表仍是有順序的。
s_urls += ss_urls 這裏採用列表鏈接的方式來獲得總的url鏈接列表。