時(shí)間:2023-06-08 03:21:02 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2023-06-08 03:21:02 來(lái)源:網(wǎng)站運(yùn)營(yíng)
3種網(wǎng)頁(yè)抓取方法:3種抓取其中數(shù)據(jù)的方法。首先是正則表達(dá)式,然后是流行的BeautifulSoup
模塊,最后是強(qiáng)大的lxml
模塊。https://docs.python.org/2/howto/regex.html
獲得完整介紹。即使你使用過(guò)其他編程語(yǔ)言的正則表達(dá)式,我依然推薦你一步一步溫習(xí)一下Python中正則表達(dá)式的寫法。code
目錄中運(yùn)行,以便導(dǎo)入工作正常。如果你希望創(chuàng)建一個(gè)不同的結(jié)構(gòu),請(qǐng)注意需要變更所有來(lái)自其他章的導(dǎo)入操作(比如下述代碼中的from chp1.advanced_link_crawler
)。>>>
import re
>>>
from chp1.advanced_link_crawler import download
>>> url =
'http://example.python-scraping.com/view/UnitedKingdom-239'
>>> html = download(url)
>>> re.findall(r'(.*?)', html)
['<img />
',
'244,820 square kilometres',
'62,348,447',
'GB',
'United Kingdom',
'London',
'<a>EU</a>
',
'.uk',
'GBP',
'Pound',
'44',
'@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
'^(([A-Z]d{2}[A-Z]{2})|([A-Z]d{3}[A-Z]{2})|([A-Z]{2}d{2} [A-Z]{
2})|([A-Z]{2}d{3}[A-Z]{2})|([A-Z]d[A-Z]d[A-Z]{2}) |([A-Z]{2}d[A-Z]
d[A-Z]{2})|(GIR0AA))$',
'en-GB,cy-GB,gd',
'<div><a>IE </a></div>
']
>>> re.findall('(.*?)', html)[1]
'244,820 square kilometres'
>>> re.findall('<label for="places_area">Area: </label>
(.*?)', html)
['244,820 square kilometres']
`標(biāo)簽之間添加多余的空格,或是變更
area_label`等。下面是嘗試支持這些可能性的改進(jìn)版本。>>> re.findall('''.*?<tds>(.*?)''', html)
['244,820 square kilometres']
`標(biāo)簽里添加
title屬性,或者
tr、
td`元素修改了它們的CSS類或ID。pip install beautifulsoup4
<ul>
<li>Area
</li><li>Population
</li></ul>
Population
列表項(xiàng)被解析為Area
列表項(xiàng)的子元素,而不是并列的兩個(gè)列表項(xiàng)的話,我們?cè)谧トr(shí)就會(huì)得到錯(cuò)誤的結(jié)果。下面讓我們看一下Beautiful Soup是如何處理的。>>>
from bs4 import
BeautifulSoup
>>>
from pprint import pprint
>>> broken_html =
'<ul><li>Area</li><li>Population</li></ul>
'
>>>
# parse the HTML
>>> soup =
BeautifulSoup(broken_html,
'html.parser')
>>> fixed_html = soup.prettify()
>>> pprint(fixed_html)
<ul>
<li>
Area
</li><li>
Population
</li>
</ul>
html.parser
并沒(méi)有得到正確解析的HTML。從前面的代碼片段可以看出,由于它使用了嵌套的li
元素,因此可能會(huì)導(dǎo)致定位困難。幸運(yùn)的是,我們還有其他解析器可以選擇。我們可以安裝LXML(2.2.3節(jié)中將會(huì)詳細(xì)介紹),或使用html5lib
。要想安裝html5lib
,只需使用pip
。pip install html5lib
>>> soup =
BeautifulSoup(broken_html,
'html5lib')
>>> fixed_html = soup.prettify()
>>> pprint(fixed_html)
<ul>
<li>
Area
</li>
<li>
Population
</li>
</ul>
html5lib
的BeautifulSoup
已經(jīng)能夠正確解析缺失的屬性引號(hào)以及閉合標(biāo)簽,并且還添加了和
標(biāo)簽,使其成為完整的HTML文檔。當(dāng)你使用lxml
時(shí),也可以看到類似的結(jié)果。find()
和find_all()
方法來(lái)定位我們需要的元素了。>>> ul = soup.find('ul', attrs={'class':'country_or_district'})
>>> ul.find('li')
# returns just the first match
<li>Area</li>
>>> ul.find_all('li')
# returns all matches
[<li>Area</li>
,
<li>Population</li>
>>>
from bs4 import
BeautifulSoup
>>> url =
'http://example.python-scraping.com/places/view/United-Kingdom-239'
>>> html = download(url)
>>> soup =
BeautifulSoup(html)
>>>
# locate the area row
>>> tr = soup.find(attrs={'id':'places_area__row'})
>>> td = tr.find(attrs={'class':'w2p_fw'})
# locate the data element
>>> area = td.text # extract the text from the data element
>>>
print(area)
244,820 square kilometres
libxml2
這一XML解析庫(kù)構(gòu)建的Python庫(kù),它使用C語(yǔ)言編寫,解析速度比Beautiful Soup更快,不過(guò)安裝過(guò)程也更為復(fù)雜,尤其是在Windows中。最新的安裝說(shuō)明可以參考http://lxml.de/installation.html
。如果你在自行安裝該庫(kù)時(shí)遇到困難,也可以使用Anaconda來(lái)實(shí)現(xiàn)。PYTHON_PATH
設(shè)置為Conda的Python安裝位置。lxml
模塊的第一步也是將有可能不合法的HTML解析為統(tǒng)一格式。下面是使用該模塊解析同一個(gè)不完整HTML的例子。>>>
from lxml.html import fromstring, tostring
>>> broken_html =
'<ul><li>Area</li><li>Population</li></ul>
'
>>> tree = fromstring(broken_html)
# parse the HTML
>>> fixed_html = tostring(tree, pretty_print=True)
>>>
print(fixed_html)
<ul>
<li>Area</li>
<li>Population</li>
</ul>
lxml
也可以正確解析屬性兩側(cè)缺失的引號(hào),并閉合標(biāo)簽,不過(guò)該模塊沒(méi)有額外添加和
標(biāo)簽。這些都不是標(biāo)準(zhǔn)XML的要求,因此對(duì)于lxml
來(lái)說(shuō),插入它們并不是必要的。lxml
有幾種不同的方法,比如XPath選擇器和類似Beautiful Soup的find()
方法。不過(guò),在本例中,我們將會(huì)使用CSS選擇器,因?yàn)樗雍?jiǎn)潔,并且能夠在第5章解析動(dòng)態(tài)內(nèi)容時(shí)得以復(fù)用。一些讀者可能由于他們?cè)趈Query選擇器方面的經(jīng)驗(yàn)或是前端Web應(yīng)用開發(fā)中的使用對(duì)它們已經(jīng)有所熟悉。在本章的后續(xù)部分,我們將對(duì)比這些選擇器與XPath的性能。要想使用CSS選擇器,你可能需要先安裝cssselect
庫(kù),如下所示。pip install cssselect
lxml
的CSS選擇器,抽取示例頁(yè)面中的面積數(shù)據(jù)了。>>> tree = fromstring(html)
>>> td = tree.cssselect('tr#places_area__row > td.w2p_fw')[0]
>>> area = td.text_content()
>>>
print(area)
244,820 square kilometres
cssselect
方法,我們可以利用CSS語(yǔ)法來(lái)選擇表格中ID為places_area__row
的行元素,然后是類為w2p_fw
的子表格數(shù)據(jù)標(biāo)簽。由于cssselect
返回的是一個(gè)列表,我們需要獲取其中的第一個(gè)結(jié)果,并調(diào)用text_content
方法,以迭代所有子元素并返回每個(gè)元素的相關(guān)文本。在本例中,盡管我們只有一個(gè)元素,但是該功能對(duì)于更加復(fù)雜的抽取示例來(lái)說(shuō)非常有用。關(guān)鍵詞:方法
客戶&案例
營(yíng)銷資訊
關(guān)于我們
客戶&案例
營(yíng)銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。