python網路爬蟲(二)

2021-07-24 04:48:13 字數 3465 閱讀 1464

在第一篇中,我們介紹了如何進行發起乙個http請求,並接受響應。在這一部分中,我們介紹一下如何解析網頁並提取我們需要的資料。

我們採用requests這個庫進行乙個網頁請求。

r = requests.get('', headers, **kwargs )
通過這一句**,我們即可獲得伺服器傳給我們的響應內容(不考慮連線錯誤等情況)。

假設返回的是200的響應。一般情況下我們請求的都是靜態的html純文字網頁,採用r.text即可獲得我們想要的網頁內容。requests會自動為我們解壓縮以及進行網頁字元解碼。預設情況下,requests會採用響應headers中的指定的字元編碼進行解碼。

如上圖所示,這是乙個非常標準的http response頭部,現在我們重點看content-type那一行,在這一行中,我們可以看到』charset=utf-8』,這就說明了網頁是採用』utf-8』字元編碼的,requests也會採用』utf-8』為網頁進行解碼,完全沒有任何問題。

但是,如果response的頭部沒有』charset=utf-8』字元編碼提示呢?那requests是如何進行解碼的呢?

上圖是requests模組對r.text這個資料描述符的解釋。我們可以看到,如果在響應的頭部沒有』charset=utf-8』,那麼requests就會用』chardet』這個模組進行編碼猜測。然後用猜測到的字元編碼進行網頁解碼。那麼,問題來了,字元編碼猜錯的可能性是存在的。那我們該如何降低這種錯誤率呢?

其實在目前大部分的網頁中(可以用4個9表示), 是給出了網頁對應的字元編碼的,如下圖所示:

很明顯,我們可以看到網頁的字元編碼是』utf-8』,所以我們就可以自己寫乙個函式,採用正則去提取這個編碼:

def

webpage_code

(response):

#解決網頁編碼問題

""" 獲取網頁的編碼

"""patten = re.compile(r'charset=(.+)[\"\']>')

if patten.search(response.content) is

notnone:

charset = patten.search(response.content).group(1)

return charset.strip("\'"

or"\"").lower()

else:#使用chardet去猜測編碼

my_stringio = stringio(response.content)

my_detector = universaldetector()

for x in my_stringio:

my_detector.feed(x)

if my_detector.done:

break

my_detector.close()

return my_detector.result['encoding']

response是我們requests返回的物件。在**的第一部分中我們利用正規表示式去檢測網頁中是否存在』charset=utf-8』。如果存在直接返回,如果不存在,我們採用chardet這個模組去檢測編碼。至於這個模組如何使用請參考官方指南。這裡不做詳細的介紹。

到這裡,我們已經解決了網頁字元編碼問題。接下來我們去提取我們想要的結構化資料。這裡我推薦使用parsel模組。parsel模組其實就是對lxml的乙個封裝,但是它使用起來非常的簡單。另外,api指南比lxml更簡潔易懂。當然,也可以使用beautifulsoup,但是它的解析網頁速度不如lxml。至於解析網頁是採用css還是xpath,隨意。我個人喜歡xpath,另外,css選擇器的底層實現就是xpath

from parsel import selector

sel = selector(html=response.text, type='html')

#在提取網頁結構化資料的時候,可以使用下面的語句

field1 = sel.xpath(xpath路徑).extract()

field2 = sel.xpath(xpath路徑).extract()

#在提取網頁鏈結的時候,可以使用下列的語句

links = sel.xpath(xpath路徑).re(正規表示式語句)

使用起來非常的簡單,不是嗎?

下面是我自己解析網頁的乙個封裝:

class

extract

(object):

def__init__

(self, text, selector):

self.sel = selector(text=text, type='html')

self.item_list =

self.link_set = set()

self.local_item = defaultdict(list)

defitem_xpath

(self, fieldname, xpath):

#提取結構化資料

value = self.sel.xpath(xpath).extract()

#提取出來的資料是乙個列表,為空或者包含乙個元素

#如果列表不為空,就把這個元素拿出來

#否則就賦予乙個空字串

item = (fieldname, value[0]) if value \

else (fieldname, '')

deflink_xpath

(self, xpath, re_patten=r'.'):

#提取鏈結

links = self.sel.xpath(xpath).re(re_patten)

self.link_set.update(links)

defget_item

(self):

for k, v in self.item_list:

for k, v in self.local_item.items():

self.local_item[k] = ','.join(v).encode('utf-8')

return self.local_item

defget_links

(self):

return list(self.link_set)

Python網路爬蟲學習(二)

十五.京東商品頁面的爬取 import requests r requests.get r.status code r.encoding r.text 1000 十六.亞馬遜商品頁面的爬取 import requests def main url try kv r requests.get url,...

python網路爬蟲入門(二)

一 python爬取10頁250條資料中的所有 書單 模組案例方法一 encoding utf 8 import requests from bs4 import beautifulsoup i 25 while i 225 i i 25 c str i resp requests.get c so...

python網路爬蟲 入門(二)

可以替代人工從網頁中找到資料並複製貼上到excel中,這種重複性的工作不僅浪費時間還一不留神還會出錯 解決無法自動化和無法實時獲取資料 對於這些公開資料的應用價值,我們可以使用kyc框架來理解,know your company 了解你的公司 know your competitor 了解你的競手 ...