Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
信息爆炸的時(shí)代,獲取和分析大量的網(wǎng)頁數(shù)據(jù)是企業(yè)和個(gè)人進(jìn)行市場調(diào)研、競爭分析等重要活動(dòng)的基礎(chǔ)。為了更高效地獲取所需數(shù)據(jù),許多人選擇使用網(wǎng)頁數(shù)據(jù)采集工具定制。今天小編就來和大家分享一下自己的經(jīng)驗(yàn),希望能給大家?guī)硪恍﹩l(fā)和幫助。
1.明確需求:在開始定制網(wǎng)頁數(shù)據(jù)采集工具之前,首先要明確自己的需求。確定需要采集的網(wǎng)站、目標(biāo)數(shù)據(jù)類型以及所需的采集頻率等。只有清楚地定義了需求,才能更好地進(jìn)行后續(xù)工作。
2.選擇合適的工具:市面上有許多網(wǎng)頁數(shù)據(jù)采集工具可供選擇,如Python中的BeautifulSoup、Scrapy等,以及專業(yè)的商業(yè)軟件。根據(jù)自身實(shí)際情況和技術(shù)水平,選擇適合自己的工具。同時(shí),也可以結(jié)合多種工具的優(yōu)勢進(jìn)行定制開發(fā)。
3.編寫采集規(guī)則:根據(jù)需求,編寫相應(yīng)的采集規(guī)則是定制網(wǎng)頁數(shù)據(jù)采集工具的關(guān)鍵步驟。通過分析目標(biāo)網(wǎng)頁的HTML結(jié)構(gòu)和元素特征,使用XPath或CSS選擇器等方式提取所需數(shù)據(jù)。在編寫規(guī)則時(shí),要考慮到網(wǎng)頁結(jié)構(gòu)的變化和數(shù)據(jù)的動(dòng)態(tài)更新,保證采集的準(zhǔn)確性和穩(wěn)定性。
4.處理反爬機(jī)制:為了防止被目標(biāo)網(wǎng)站的反爬機(jī)制攔截,我們需要采取一些措施來規(guī)避。可以設(shè)置合理的請求頭信息、使用代理IP進(jìn)行訪問、模擬人類操作行為等。這樣可以提高采集的成功率,并降低被封禁的風(fēng)險(xiǎn)。
5.數(shù)據(jù)清洗和存儲(chǔ):采集回來的數(shù)據(jù)往往會(huì)包含各種噪聲和冗余信息,需要進(jìn)行數(shù)據(jù)清洗和預(yù)處理。可以使用正則表達(dá)式、字符串處理函數(shù)等方法進(jìn)行數(shù)據(jù)清洗,去除無用字符、格式化數(shù)據(jù)等。同時(shí),選擇合適的數(shù)據(jù)庫或文件格式來存儲(chǔ)采集到的數(shù)據(jù),方便后續(xù)分析和使用。
6.定期維護(hù)和更新:網(wǎng)頁結(jié)構(gòu)和數(shù)據(jù)源都可能會(huì)發(fā)生變化,因此定期維護(hù)和更新是非常重要的。及時(shí)調(diào)整采集規(guī)則,修復(fù)可能出現(xiàn)的錯(cuò)誤,并保持與目標(biāo)網(wǎng)站的同步。同時(shí),也要關(guān)注目標(biāo)網(wǎng)站是否有新的反爬機(jī)制出現(xiàn),及時(shí)調(diào)整策略以確保持續(xù)穩(wěn)定地進(jìn)行數(shù)據(jù)采集。
7.合法合規(guī)操作:在進(jìn)行網(wǎng)頁數(shù)據(jù)采集時(shí),要遵守相關(guān)法律法規(guī)和網(wǎng)站的使用協(xié)議,確保自己的操作合法合規(guī)。不得利用采集工具進(jìn)行非法活動(dòng),如侵犯他人隱私、侵權(quán)等。同時(shí),在采集過程中要遵守網(wǎng)站的訪問頻率限制,以免給目標(biāo)網(wǎng)站帶來過大的壓力。
通過以上經(jīng)驗(yàn)分享,相信大家對于網(wǎng)頁數(shù)據(jù)采集工具定制有了更清晰的認(rèn)識(shí)。在實(shí)際操作中,需要不斷學(xué)習(xí)和探索,結(jié)合自身需求靈活運(yùn)用各種技術(shù)手段,才能更好地應(yīng)對復(fù)雜多變的數(shù)據(jù)采集任務(wù)。希望本文對大家有所幫助,祝愿大家在定制網(wǎng)頁數(shù)據(jù)采集工具的道路上取得更好的成果!
任何問題可聯(lián)系我,我們一起學(xué)習(xí)!:)
第一步:下載HTML頁面
基本下載網(wǎng)頁的能力包括針對 URL 進(jìn)行 HTTP GET 請求。這是任何 web 瀏覽器的基本操作。讓我們快速回顧一下此操作的不同部分,因?yàn)樗腥齻€(gè)不同的元素:
使用 HTTP 協(xié)議。這涉及請求的結(jié)構(gòu)方式。
使用 GET 方法,這是最常見的 HTTP 方法。我們將在訪問 web API 的示例中進(jìn)一步了解它。
完整的 URL 描述了頁面的地址,包括服務(wù)器(例如:mypage.com)和路徑(例如:/page)。
該請求將通過互聯(lián)網(wǎng)路由到服務(wù)器,并由服務(wù)器進(jìn)行處理,然后將返回響應(yīng)。該響應(yīng)將包含狀態(tài)代碼,通常是 200,如果一切正常,以及結(jié)果的正文,這通常是帶有 HTML 頁面的文本。
大部分請求自動(dòng)處理了 HTTP 客戶端。在這個(gè)示例中,我們將看到如何簡單請求以獲取 web 頁面。
HTTP 請求和響應(yīng)也可以包含頭部信息。頭部信息包含了關(guān)于請求本身的重要信息,例如請求的總大小,內(nèi)容的格式,請求的日期以及使用的瀏覽器或服務(wù)器等。
準(zhǔn)備工作
使用出色的 requests 模塊,獲取網(wǎng)頁非常簡單。安裝模塊:
$ echo "requests==2.23.0" >> requirements.txt
$ source .venv/bin/activate
(.venv) $ pip install -r requirements.txt
我們將下載位于 http://www.columbia.edu/~fdc/sample.html 的頁面,因?yàn)樗且粋€(gè)簡單的 HTML 頁面,易于在文本模式下閱讀。
操作步驟:
導(dǎo)入requests模塊:
import requests
使用以下URL向服務(wù)器發(fā)出請求,需要一兩秒鐘的時(shí)間:
url = 'http://www.columbia.edu/~fdc/sample.html'
response = requests.get(url)
檢查返回對象的狀態(tài)碼:
response.status_code
200
檢查結(jié)果的內(nèi)容:
response.text
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
n<html>\n<head>\n
...
完整的HTML代碼
...
<!-- close the <html> begun above -->\n'
檢查正在進(jìn)行和返回的標(biāo)頭:
response.request.headers
{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip,
deflate', 'Accept': '/', 'Connection': 'keep-alive'}
response.headers
{'Date': 'Fri, 24 Jan 2020 19:04:12 GMT', 'Server': 'Apache',
'Last-Modified': 'Wed, 11 Dec 2019 12:46:44 GMT', 'Accept-Ranges':
'bytes', 'Vary': 'Accept-Encoding,User-Agent', 'Content-Encoding':
'gzip', 'Content-Length': '10127', 'Keep-Alive': 'timeout=15,
max=100', 'Connection': 'Keep-Alive', 'Content-Type': 'text/
html', 'Set-Cookie': 'BIGipServerCUITwww.columbia.edu-80-
pool=1311259520.20480.0000; expires=Sat, 25-Jan-2020 01:04:12 GMT;
path=/; Httponly'}
它是如何工作的...
requests 的操作非常簡單;在此情況下,使用 GET 方法在 URL 上執(zhí)行請求。這將返回一個(gè)結(jié)果對象,可以進(jìn)行分析。主要元素是狀態(tài)代碼和正文內(nèi)容,可以表示為文本。
完整的請求可以在請求屬性中檢查:
response.request
<PreparedRequest [GET]>
response.request.url
http://www.columbia.edu/~fdc/sample.html'
完整的 requests 模塊文檔可以在這里找到:https://requests.readthedocs.io/en/master/。
在本章的過程中,我們將展示更多 requests 庫的特點(diǎn)。
還有更多...
所有 HTTP 狀態(tài)代碼可以在此網(wǎng)頁中查看:https://httpstatuses.com/。它們也在 http.HTTPStatus 枚舉中描述,具有方便的常量名稱,如 OK、NOT_FOUND 或 FORBIDDEN。
狀態(tài)代碼的一般結(jié)構(gòu)是:
1XX - 關(guān)于協(xié)議的具體信息。
2XX - 成功。
3XX - 重定向。例如:URL 不再有效,并且可在其他地方找到。新的 URL 應(yīng)該被包含在內(nèi)。
4XX - 客戶端錯(cuò)誤。在向服務(wù)器發(fā)送信息時(shí)存在一些錯(cuò)誤(例如,格式錯(cuò)誤),或者客戶端存在錯(cuò)誤(例如,需要身份驗(yàn)證才能訪問 URL)。
最著名的錯(cuò)誤狀態(tài)代碼可能是 404,當(dāng)描述 URL 的資源未找到時(shí)返回該代碼。嘗試通過執(zhí)行 requests.get(http://www.columbia.edu/invalid) 進(jìn)行測試。
5XX - 服務(wù)器錯(cuò)誤。服務(wù)器端存在錯(cuò)誤;例如,服務(wù)器可能不可用,或者處理請求時(shí)可能存在錯(cuò)誤。
請求可以使用 HTTPS(安全 HTTP)協(xié)議。它與 HTTP 相同,但確保請求和響應(yīng)的內(nèi)容是私有的。requests 會(huì)自動(dòng)處理它。
任何處理任何私人信息的網(wǎng)站都應(yīng)該使用HTTPS來確保信息沒有泄漏。HTTP容易被竊聽。請?jiān)谟锌赡艿那闆r下使用HTTPS。
第二步:解析HTML
下載原始文本或二進(jìn)制文件是一個(gè)好的起點(diǎn),但是網(wǎng)絡(luò)的主要語言是HTML。
HTML是一種結(jié)構(gòu)化語言,定義了文檔的不同部分,例如標(biāo)題和段落。HTML也是分層的,定義了子元素。將原始文本解析為結(jié)構(gòu)化文檔的能力基本上是從網(wǎng)頁自動(dòng)提取信息的能力。例如,如果將某些文本放入特定的HTML元素中,例如class div或heading h3標(biāo)記之后,則可能是相關(guān)的文本。
準(zhǔn)備就緒
我們將使用優(yōu)秀的Beautiful Soup模塊將HTML文本解析為可以分析的內(nèi)存對象。我們需要使用最新版本的beautifulsoup4包與Python 3兼容。將該包添加到您的requirements.txt文件中,并在虛擬環(huán)境中安裝依賴項(xiàng):
$ echo "beautifulsoup4==4.8.2" >> requirements.txt
$ pip install -r requirements.txt
如何完成它...
導(dǎo)入 BeautifulSoup 和 requests 模塊:
import requests
from bs4 import BeautifulSoup
設(shè)置要下載和獲取的頁面的 URL:
URL = 'http://www.columbia.edu/~fdc/sample.html'
response = requests.get(URL)
response
<Response [200]>
解析已下載的頁面:
page = BeautifulSoup(response.text, 'html.parser')
獲取頁面標(biāo)題。查看它是否與瀏覽器中顯示的相同:
page.title
<title>Sample Web Page</title>
>>> page.title.string
'Sample Web Page'
5. 找到頁面中的所有 h3 元素,以確定現(xiàn)有部分:
>>> page.find_all('h3')
[<h3><a name="contents">CONTENTS</a></h3>, <h3><a name="basics">1.
Creating a Web Page</a></h3>, <h3><a name="syntax">2. HTML
Syntax</a></h3>, <h3><a name="chars">3. Special Characters</a></
h3>, <h3><a name="convert">4. Converting Plain Text to HTML</
a></h3>, <h3><a name="effects">5. Effects</a></h3>, <h3><a
name="lists">6. Lists</a></h3>, <h3><a name="links">7. Links</
a></h3>, <h3><a name="tables">8. Tables</a></h3>, <h3><a
name="install">9. Installing Your Web Page on the Internet</a></
h3>, <h3><a name="more">10. Where to go from here</a></h3>]
6. 提取特殊字符部分的文本。當(dāng)遇到下一個(gè) <h3> 標(biāo)簽時(shí)停止:
>>> link_section = page.find('h3', attrs={'id': 'chars'})
>>> section = []
for element in link_section.next_elements:
... if element.name == 'h3':
... break
... section.append(element.string or '')
...
result = ''.join(section)
result
'3. Special Characters\n\nHTML特殊“字符實(shí)體”以和號(&&)開頭并以分號(;;)結(jié)束,例如"€€" = "€"。永遠(yuǎn)流行的“不換行空格”是 。有用于重音拉丁字母和其他西歐特殊字符的特殊實(shí)體名稱,例如:\n\n\n\n\n\n??\na-umlaut\n\xa0?\xa0\n\n\n??\nA-umlaut\n\xa0?\xa0\n\n\náá\na-acute\n\xa0á\xa0\n\nàà\na-grave\n\xa0à\xa0\n\n??\nn-tilde\n\xa0?\xa0\n\n??\nGerman double-s\n\xa0?\xa0\n\ntt\nIcelandic thorn\n\xa0t\xa0\n\xa0t\xa0\n\n\n\n\n示例:\n\n\n對于西班牙語,您需要:\náá (á),\náá (á),\néé (é),\néé (é),\níí (í),\níí (í),\nóó (ó),\nóó (ó),\núú (ú),\núú (ú),\n?? (?),\n?? (?);\n?? (?);\n?? (?)。\n例如:A?orarán = A?oraránA?orarán。\n\n\n對于德語,您需要:\n?? (?),\n?? (?),\n?? (?),\n?? (?),\nüü (ü),\nüü (ü),\n?? (?)。\n例如:Grü?e aus K?ln = Grü?e aus K?lnGrü?e aus K?ln。\n\n\n\n點(diǎn)擊此處\n點(diǎn)擊此處\n以獲取完整列表。建議頁面編碼為UTF-8,這樣您也可以直接從鍵盤輸入任何字符,無論是羅馬字母、西里爾字母、阿拉伯字母、
它是如何工作的...
第一步是下載頁面。然后,可以像第3步那樣解析原始文本。
生成的頁面對象包含了解析后的信息。
BeautifulSoup允許我們搜索HTML元素。它可以使用.find()搜索第一個(gè)HTML元素,或使用.find_all()返回一個(gè)列表。
在第5步中,它搜索了一個(gè)特定的標(biāo)簽<a>,該標(biāo)簽具有特定的屬性id=chars。
然后,它繼續(xù)迭代.next_elements,直到找到下一個(gè)h3標(biāo)簽,該標(biāo)簽標(biāo)志著該節(jié)的結(jié)束。
提取每個(gè)元素的文本,最后組合成一個(gè)單一的文本。請注意,使用or可以避免存儲(chǔ)None,當(dāng)元素沒有文本時(shí)返回None。
還有更多...
正則表達(dá)式可以用作.find()和.find_all()方法的輸入。例如,此搜索使用h2和h3標(biāo)記:
page.find_all(re.compile('^h(2|3)'))
[<h2>Sample Web Page</h2>, <h3 id="contents">CONTENTS</h3>, <h3
id="basics">1. Creating a Web Page</h3>, <h3 id="syntax">2. HTML Syntax</
h3>, <h3 id="chars">3. Special Characters</h3>, <h3 id="convert">4.
Converting Plain Text to HTML</h3>, <h3 id="effects">5. Effects</
h3>, <h3 id="lists">6. Lists</h3>, <h3 id="links">7. Links</h3>, <h3
id="tables">8. Tables</h3>, <h3 id="viewing">9. Viewing Your Web Page</
h3>, <h3 id="install">10. Installing Your Web Page on the Internet</h3>,
<h3 id="more">11. Where to go from here</h3>]
html.parser解析器是默認(rèn)的解析器,但對于某些操作,它可能會(huì)有問題。例如,對于大頁面,它可能會(huì)很慢,并且它可能會(huì)在渲染高度動(dòng)態(tài)的網(wǎng)頁時(shí)出現(xiàn)問題。您可以使用其他解析器,例如lxml,它更快,或html5lib,它將更接近瀏覽器的操作方式。它們是需要添加到requirements.txt文件中的外部模塊。
HTML非常靈活,可以有多種結(jié)構(gòu)。本篇案例是典型的,但其他選項(xiàng)可將相關(guān)部分組合在大的<div>標(biāo)記或其他元素內(nèi),甚至可以使用原始文本。需要進(jìn)行一些實(shí)驗(yàn),才能找到提取網(wǎng)頁中的精華部分的具體過程。不要害怕嘗試!
另一個(gè)有用的查找參數(shù)是使用class_參數(shù)包含CSS類。這將在本書的后面展示。
完整的Beautiful Soup文檔可以在此處找到:https://www.crummy.com/software/BeautifulSoup/bs4/doc/。
eautifulsoup介紹:
第一步:安裝BeautifulSoup4,lxml
pip install BeautifulSoup4
BeautifulSoup 是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫
pip install lxml
lxml 是一種使用 Python 編寫的解析庫,可以迅速、靈活地處理 XML 和 HTML
第二步:導(dǎo)包,from bs4 import BeautifulSoup
第三步:實(shí)例化對象
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
and they lived at the bottom of a well.
</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html, 'lxml') # h:要解析的內(nèi)容 lxml:解析器
知識(shí)補(bǔ)充:print(soup.prettify()) # 代碼補(bǔ)全
第四步:打印
一、通過標(biāo)簽選取,會(huì)返回包含標(biāo)簽本身及其里面的所有內(nèi)容
# print(soup.head) # 包含head標(biāo)簽在內(nèi)的所有內(nèi)容
# print(soup.p) # 返回匹配的第一個(gè)結(jié)果
1.print(soup.head)打印結(jié)果:
<head>
<title>The Dormouse's story</title>
</head>
2.print(soup.p)打印結(jié)果:
<p class="title" name="dromouse"><b><span>The Dormouse's story</span></b></p>
二、打印標(biāo)簽中間的文本內(nèi)容,不包含<>
# .string是屬性,作用是獲取字符串文本
print(soup.html.head.title.string)
print(soup.title.string)
打印結(jié)果都為:The Dormouse's story
三、打印標(biāo)簽名
.name --獲取標(biāo)簽本身名稱
print(soup.title.name)
打印結(jié)果為:title
四、打印屬性的值
.attrs[] --通過屬性拿屬性的值
print(soup.p.attrs['name'])# 獲取p標(biāo)簽name屬性的屬性值
print(soup.a.attrs['id']) # 獲取p標(biāo)簽id屬性的屬性值
print(soup.a['id']) #第二種寫法
print(soup.p['class']) # 以列表得形式保存
print(soup.a['href']) # 也是只返回第一個(gè)值
1.print(soup.p.attrs['name'])打印結(jié)果:
dromouse
2.print(soup.p.attrs['id'])和print(soup.a['id'])打印結(jié)果:
link1
3.print(soup.p['class'])打印結(jié)果:
['title', 'asdas']
4.print(soup.a['href'])打印結(jié)果:
http://example.com/elsie
五、打印父標(biāo)簽下的所有子標(biāo)簽
.contents 獲取標(biāo)簽子節(jié)點(diǎn),以列表形式返回
.children 獲取子節(jié)點(diǎn),返回的是一個(gè)list類型的迭代器
print(soup.body.contents) # a是p的子節(jié)點(diǎn),獲取P標(biāo)簽所有子節(jié)點(diǎn)內(nèi)容 返回一個(gè)list
print(soup.body.children) #返回的是一個(gè)list類型的迭代器
1.print(soup.body.contents)的打印結(jié)果:
['\n', <p class="title asdas" name="dromouse"><b><span>The Dormouse's story</span></b></p>, '\n', <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, '\n', <p class="story">...</p>, '\n']
2.print(soup.body.children)的打印結(jié)果:
<list_iterator object at 0x000002035ECC7088>
.children 獲取子節(jié)點(diǎn)講解
1.和for循環(huán)一起使用
for i in soup.p.children:
print(i)
打印結(jié)果:
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。