信息爆炸的時代,獲取和分析大量的網頁數據是企業和個人進行市場調研、競爭分析等重要活動的基礎。為了更高效地獲取所需數據,許多人選擇使用網頁數據采集工具定制。今天小編就來和大家分享一下自己的經驗,希望能給大家帶來一些啟發和幫助。
1.明確需求:在開始定制網頁數據采集工具之前,首先要明確自己的需求。確定需要采集的網站、目標數據類型以及所需的采集頻率等。只有清楚地定義了需求,才能更好地進行后續工作。
2.選擇合適的工具:市面上有許多網頁數據采集工具可供選擇,如Python中的BeautifulSoup、Scrapy等,以及專業的商業軟件。根據自身實際情況和技術水平,選擇適合自己的工具。同時,也可以結合多種工具的優勢進行定制開發。
3.編寫采集規則:根據需求,編寫相應的采集規則是定制網頁數據采集工具的關鍵步驟。通過分析目標網頁的HTML結構和元素特征,使用XPath或CSS選擇器等方式提取所需數據。在編寫規則時,要考慮到網頁結構的變化和數據的動態更新,保證采集的準確性和穩定性。
4.處理反爬機制:為了防止被目標網站的反爬機制攔截,我們需要采取一些措施來規避。可以設置合理的請求頭信息、使用代理IP進行訪問、模擬人類操作行為等。這樣可以提高采集的成功率,并降低被封禁的風險。
5.數據清洗和存儲:采集回來的數據往往會包含各種噪聲和冗余信息,需要進行數據清洗和預處理。可以使用正則表達式、字符串處理函數等方法進行數據清洗,去除無用字符、格式化數據等。同時,選擇合適的數據庫或文件格式來存儲采集到的數據,方便后續分析和使用。
6.定期維護和更新:網頁結構和數據源都可能會發生變化,因此定期維護和更新是非常重要的。及時調整采集規則,修復可能出現的錯誤,并保持與目標網站的同步。同時,也要關注目標網站是否有新的反爬機制出現,及時調整策略以確保持續穩定地進行數據采集。
7.合法合規操作:在進行網頁數據采集時,要遵守相關法律法規和網站的使用協議,確保自己的操作合法合規。不得利用采集工具進行非法活動,如侵犯他人隱私、侵權等。同時,在采集過程中要遵守網站的訪問頻率限制,以免給目標網站帶來過大的壓力。
通過以上經驗分享,相信大家對于網頁數據采集工具定制有了更清晰的認識。在實際操作中,需要不斷學習和探索,結合自身需求靈活運用各種技術手段,才能更好地應對復雜多變的數據采集任務。希望本文對大家有所幫助,祝愿大家在定制網頁數據采集工具的道路上取得更好的成果!
任何問題可聯系我,我們一起學習!:)
第一步:下載HTML頁面
基本下載網頁的能力包括針對 URL 進行 HTTP GET 請求。這是任何 web 瀏覽器的基本操作。讓我們快速回顧一下此操作的不同部分,因為它有三個不同的元素:
使用 HTTP 協議。這涉及請求的結構方式。
使用 GET 方法,這是最常見的 HTTP 方法。我們將在訪問 web API 的示例中進一步了解它。
完整的 URL 描述了頁面的地址,包括服務器(例如:mypage.com)和路徑(例如:/page)。
該請求將通過互聯網路由到服務器,并由服務器進行處理,然后將返回響應。該響應將包含狀態代碼,通常是 200,如果一切正常,以及結果的正文,這通常是帶有 HTML 頁面的文本。
大部分請求自動處理了 HTTP 客戶端。在這個示例中,我們將看到如何簡單請求以獲取 web 頁面。
HTTP 請求和響應也可以包含頭部信息。頭部信息包含了關于請求本身的重要信息,例如請求的總大小,內容的格式,請求的日期以及使用的瀏覽器或服務器等。
準備工作
使用出色的 requests 模塊,獲取網頁非常簡單。安裝模塊:
$ echo "requests==2.23.0" >> requirements.txt
$ source .venv/bin/activate
(.venv) $ pip install -r requirements.txt
我們將下載位于 http://www.columbia.edu/~fdc/sample.html 的頁面,因為它是一個簡單的 HTML 頁面,易于在文本模式下閱讀。
操作步驟:
導入requests模塊:
import requests
使用以下URL向服務器發出請求,需要一兩秒鐘的時間:
url = 'http://www.columbia.edu/~fdc/sample.html'
response = requests.get(url)
檢查返回對象的狀態碼:
response.status_code
200
檢查結果的內容:
response.text
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
n<html>\n<head>\n
...
完整的HTML代碼
...
<!-- close the <html> begun above -->\n'
檢查正在進行和返回的標頭:
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 上執行請求。這將返回一個結果對象,可以進行分析。主要元素是狀態代碼和正文內容,可以表示為文本。
完整的請求可以在請求屬性中檢查:
response.request
<PreparedRequest [GET]>
response.request.url
http://www.columbia.edu/~fdc/sample.html'
完整的 requests 模塊文檔可以在這里找到:https://requests.readthedocs.io/en/master/。
在本章的過程中,我們將展示更多 requests 庫的特點。
還有更多...
所有 HTTP 狀態代碼可以在此網頁中查看:https://httpstatuses.com/。它們也在 http.HTTPStatus 枚舉中描述,具有方便的常量名稱,如 OK、NOT_FOUND 或 FORBIDDEN。
狀態代碼的一般結構是:
1XX - 關于協議的具體信息。
2XX - 成功。
3XX - 重定向。例如:URL 不再有效,并且可在其他地方找到。新的 URL 應該被包含在內。
4XX - 客戶端錯誤。在向服務器發送信息時存在一些錯誤(例如,格式錯誤),或者客戶端存在錯誤(例如,需要身份驗證才能訪問 URL)。
最著名的錯誤狀態代碼可能是 404,當描述 URL 的資源未找到時返回該代碼。嘗試通過執行 requests.get(http://www.columbia.edu/invalid) 進行測試。
5XX - 服務器錯誤。服務器端存在錯誤;例如,服務器可能不可用,或者處理請求時可能存在錯誤。
請求可以使用 HTTPS(安全 HTTP)協議。它與 HTTP 相同,但確保請求和響應的內容是私有的。requests 會自動處理它。
任何處理任何私人信息的網站都應該使用HTTPS來確保信息沒有泄漏。HTTP容易被竊聽。請在有可能的情況下使用HTTPS。
第二步:解析HTML
下載原始文本或二進制文件是一個好的起點,但是網絡的主要語言是HTML。
HTML是一種結構化語言,定義了文檔的不同部分,例如標題和段落。HTML也是分層的,定義了子元素。將原始文本解析為結構化文檔的能力基本上是從網頁自動提取信息的能力。例如,如果將某些文本放入特定的HTML元素中,例如class div或heading h3標記之后,則可能是相關的文本。
準備就緒
我們將使用優秀的Beautiful Soup模塊將HTML文本解析為可以分析的內存對象。我們需要使用最新版本的beautifulsoup4包與Python 3兼容。將該包添加到您的requirements.txt文件中,并在虛擬環境中安裝依賴項:
$ echo "beautifulsoup4==4.8.2" >> requirements.txt
$ pip install -r requirements.txt
如何完成它...
導入 BeautifulSoup 和 requests 模塊:
import requests
from bs4 import BeautifulSoup
設置要下載和獲取的頁面的 URL:
URL = 'http://www.columbia.edu/~fdc/sample.html'
response = requests.get(URL)
response
<Response [200]>
解析已下載的頁面:
page = BeautifulSoup(response.text, 'html.parser')
獲取頁面標題。查看它是否與瀏覽器中顯示的相同:
page.title
<title>Sample Web Page</title>
>>> page.title.string
'Sample Web Page'
5. 找到頁面中的所有 h3 元素,以確定現有部分:
>>> 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. 提取特殊字符部分的文本。當遇到下一個 <h3> 標簽時停止:
>>> 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特殊“字符實體”以和號(&&)開頭并以分號(;;)結束,例如"€€" = "€"。永遠流行的“不換行空格”是 。有用于重音拉丁字母和其他西歐特殊字符的特殊實體名稱,例如:\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點擊此處\n點擊此處\n以獲取完整列表。建議頁面編碼為UTF-8,這樣您也可以直接從鍵盤輸入任何字符,無論是羅馬字母、西里爾字母、阿拉伯字母、
它是如何工作的...
第一步是下載頁面。然后,可以像第3步那樣解析原始文本。
生成的頁面對象包含了解析后的信息。
BeautifulSoup允許我們搜索HTML元素。它可以使用.find()搜索第一個HTML元素,或使用.find_all()返回一個列表。
在第5步中,它搜索了一個特定的標簽<a>,該標簽具有特定的屬性id=chars。
然后,它繼續迭代.next_elements,直到找到下一個h3標簽,該標簽標志著該節的結束。
提取每個元素的文本,最后組合成一個單一的文本。請注意,使用or可以避免存儲None,當元素沒有文本時返回None。
還有更多...
正則表達式可以用作.find()和.find_all()方法的輸入。例如,此搜索使用h2和h3標記:
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解析器是默認的解析器,但對于某些操作,它可能會有問題。例如,對于大頁面,它可能會很慢,并且它可能會在渲染高度動態的網頁時出現問題。您可以使用其他解析器,例如lxml,它更快,或html5lib,它將更接近瀏覽器的操作方式。它們是需要添加到requirements.txt文件中的外部模塊。
HTML非常靈活,可以有多種結構。本篇案例是典型的,但其他選項可將相關部分組合在大的<div>標記或其他元素內,甚至可以使用原始文本。需要進行一些實驗,才能找到提取網頁中的精華部分的具體過程。不要害怕嘗試!
另一個有用的查找參數是使用class_參數包含CSS類。這將在本書的后面展示。
完整的Beautiful Soup文檔可以在此處找到:https://www.crummy.com/software/BeautifulSoup/bs4/doc/。
eautifulsoup介紹:
第一步:安裝BeautifulSoup4,lxml
pip install BeautifulSoup4
BeautifulSoup 是一個可以從HTML或XML文件中提取數據的Python庫
pip install lxml
lxml 是一種使用 Python 編寫的解析庫,可以迅速、靈活地處理 XML 和 HTML
第二步:導包,from bs4 import BeautifulSoup
第三步:實例化對象
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:要解析的內容 lxml:解析器
知識補充:print(soup.prettify()) # 代碼補全
第四步:打印
一、通過標簽選取,會返回包含標簽本身及其里面的所有內容
# print(soup.head) # 包含head標簽在內的所有內容
# print(soup.p) # 返回匹配的第一個結果
1.print(soup.head)打印結果:
<head>
<title>The Dormouse's story</title>
</head>
2.print(soup.p)打印結果:
<p class="title" name="dromouse"><b><span>The Dormouse's story</span></b></p>
二、打印標簽中間的文本內容,不包含<>
# .string是屬性,作用是獲取字符串文本
print(soup.html.head.title.string)
print(soup.title.string)
打印結果都為:The Dormouse's story
三、打印標簽名
.name --獲取標簽本身名稱
print(soup.title.name)
打印結果為:title
四、打印屬性的值
.attrs[] --通過屬性拿屬性的值
print(soup.p.attrs['name'])# 獲取p標簽name屬性的屬性值
print(soup.a.attrs['id']) # 獲取p標簽id屬性的屬性值
print(soup.a['id']) #第二種寫法
print(soup.p['class']) # 以列表得形式保存
print(soup.a['href']) # 也是只返回第一個值
1.print(soup.p.attrs['name'])打印結果:
dromouse
2.print(soup.p.attrs['id'])和print(soup.a['id'])打印結果:
link1
3.print(soup.p['class'])打印結果:
['title', 'asdas']
4.print(soup.a['href'])打印結果:
http://example.com/elsie
五、打印父標簽下的所有子標簽
.contents 獲取標簽子節點,以列表形式返回
.children 獲取子節點,返回的是一個list類型的迭代器
print(soup.body.contents) # a是p的子節點,獲取P標簽所有子節點內容 返回一個list
print(soup.body.children) #返回的是一個list類型的迭代器
1.print(soup.body.contents)的打印結果:
['\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)的打印結果:
<list_iterator object at 0x000002035ECC7088>
.children 獲取子節點講解
1.和for循環一起使用
for i in soup.p.children:
print(i)
打印結果:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。