Python網頁爬蟲是現在非常受歡迎的資料蒐集方式之一,而在定期爬取的過程中,非常有機會因為網頁架構或樣式的改變,導致Python網頁爬蟲發生錯誤中斷。所以,本文提供以下6個檢查點,只要在開發時特別留意,將會讓Python網頁爬蟲較為穩定及有效率。包含:
- 設定HTTP Headers(標頭)
- 設定HTTP Request timeout(超時)屬性
- 檢查HTTP Status Code(狀態碼)
- 檢查爬取的元素是否存在
- 例外處理機制
- 檔案輸入/出(I/O)機制
一、設定HTTP Headers(標頭)
由於現在很多人使用Python網頁爬蟲爬取所需的資料,因此,有些網站會針對網頁爬蟲進行偵測,當Python網頁爬蟲沒有設定HTTP Headers(標頭),很容易就會被擋下來。
所以,Python網頁爬蟲在發送請求時,最好要設定HTTP Headers(標頭),如下範例:
import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' } response = requests.get(url, headers=headers, timeout=5)
如果不知道自己的User Agent(使用者代理),可以在Google搜尋的地方輸入「what is my user agnet」,按下搜尋即可得到。
二、設定HTTP Request timeout(超時)屬性
Python網頁爬蟲在發送請求時,如果沒有設定timeout(超時)屬性,當目標網站沒有回應,請求將會持續嘗試和等待回應,除了造成目標網站的困擾,Python網頁爬蟲也無法繼續執行。而設定的方式如下範例第8行:
import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' } response = requests.get(url, headers=headers, timeout=5)
只要Python網頁爬蟲發送請求後,5秒內沒有接收回應,就會停止嘗試和等待。
三、檢查HTTP Status Code(狀態碼)
Python網頁爬蟲接收到網站的回應結果後,最好可以檢查HTTP Status Code(狀態碼)來確認是否正確,如下範例第10行:
import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' } response = requests.get(url, headers=headers, timeout=5) if response.status_code == 200: #正確 #接續執行
或是如下範例:
import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' } response = requests.get(url, headers=headers, timeout=5) if response.status_code != 200: #不正確 return False
四、檢查爬取的元素是否存在
Python網頁爬蟲最普遍會遇到的問題,就是網頁的元素或樣式改變,導致整個網頁爬蟲中斷和發生錯誤。而最好的預防方法就是先檢查爬取的元素(Element)是否存在,再執行其它的任務,如下範例:
soup = BeautifulSoup(response.content, 'lxml') title = soup.find('h3', {'class': 'post_title'}) if title: #標題元素存在 #接續執行 else: # 顯示警告訊息或發送訊息給管理人員
五、例外處理機制
為了預防Python網頁爬蟲在執行的過程中,發生預期外的錯誤,以及後續能夠有效追蹤問題,最好實作例外處理機制,如下範例:
try:
# 爬蟲邏輯
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
response = requests.get(url, headers=headers, timeout=5)
if response.status_code == 200: #正確
soup = BeautifulSoup(response.content, 'lxml')
titles = soup.find_all('h3', {'class': 'post_title'})
result = []
for title in titles:
if title:
result.append(title.getText())
else:
print('元素不存在')
else:
print('回應結果錯誤')
except requests.ConnectionError as conn_ex:
print("連線錯誤")
print(str(conn_ex))
except requests.Timeout as timeout_ex:
print("請求超時錯誤")
print(str(timeout_ex))
except requests.RequestException as request_ex:
print("請求發生錯誤")
print(str(request_ex))
except Exception as e:
print("發生其它錯誤")
print(str(e))
六、檔案輸入/出(I/O)機制
Python網頁爬蟲爬取到資料後,最常見的就是資料儲存,像是寫入資料庫、CSV或文字檔等,相較於在爬取的迴圈中進行讀、寫操作,會建議先將爬取的資料打包成串列(List)、元組(Tuple)或字典(Dictionary)等,爬取結束時再一次性寫入較有效率。如下範例:
try:
# 爬蟲邏輯
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
response = requests.get(url, headers=headers, timeout=5)
if response.status_code == 200: #正確
soup = BeautifulSoup(response.content, 'lxml')
titles = soup.find_all('h3', {'class': 'post_title'})
result = []
for title in titles:
if title:
result.append(title.getText())
else:
print('元素不存在')
else:
print('回應結果錯誤')
except requests.ConnectionError as conn_ex:
print("連線錯誤")
print(str(conn_ex))
except requests.Timeout as timeout_ex:
print("請求超時錯誤")
print(str(timeout_ex))
except requests.RequestException as request_ex:
print("請求發生錯誤")
print(str(request_ex))
except Exception as e:
print("發生其它錯誤")
print(str(e))
finally:
try:
with open('post.txt', 'w') as file:
file.write('\n'.join(result)) #寫入爬取結果
except Exception as ex:
print(str(ex))
以上範例的第11~17行將爬取的標題資料先存入串列(List)中,等到所有標題資料都爬取完畢後,第37、38行再將串列(List)中的所有標題資料一次寫入到文字檔中。
七、小結
想要讓Python網頁爬蟲更加穩定,本文提供以上6個檢查項目,希望有助於大家開發出有效率的Python網頁爬蟲。如果有其它可以增加Python網頁爬蟲執行順利的方法,也歡迎在底下留言和我分享唷 :)
本文如果有幫助到您,別忘了在下面訂閱本網站,以及幫我按五下Like(使用Google或Facebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。
有想要看的教學內容嗎?歡迎利用以下的Google表單讓我知道,將有機會成為教學文章,分享給大家😊
Python學習資源
Python網頁爬蟲推薦課程
Python非同步網頁爬蟲
Python網頁爬蟲應用
Python網頁爬蟲部署
Python網頁爬蟲資料儲存
Python網頁爬蟲技巧
- [Python爬蟲教學]學會Python網頁爬蟲輪流或隨機使用Proxy IP發送請求的技巧
- [Python爬蟲教學]有效利用Python網頁爬蟲爬取免費的Proxy IP清單
- [Python爬蟲教學]常見的Python網頁爬蟲自動化下載檔案資料方法
- [Python爬蟲教學]一學就會的Python網頁爬蟲動態讀取資料庫應用
- [Python爬蟲教學]Selenium動態網頁爬蟲通過Captcha驗證碼的實用技巧
- [Python爬蟲教學]Python網頁爬蟲動態翻頁的實作技巧
- [Python爬蟲教學]7個降低Python網頁爬蟲被偵測封鎖的實用方法
- 解析Python網頁爬蟲如何有效整合Pandas套件提升資料處理效率
- BeautifulSoup vs Selenium vs Scrapy三大Python網頁爬蟲實作工具的比較
- 必學的Python Selenium套件自動化網頁截圖技巧
因為最近在寫研究所論文,此次的論文使用Python爬蟲並將爬出來的資料進行計算新聞情緒的部份,以下有一個問題是我試了好多天,並找了好多資料、試過無數次方法,都無法解決了,在麻煩神人幫忙協助,謝謝🙏
回覆刪除此次爬蟲引用到的套件如下:
👉pandas、selenium 、bs4、requests
這次爬蟲對象為Facebook 的某社團,作業系統為:windows,下載的ChromeDriver為chrome版本95.0.4638,32bit
這次問題為當在爬蟲時爬到一半,網站就會出現「out of memory」,因此寫程式去清空了chrome暫存記憶體,但還是一樣!
綜上,因為記憶體不足的問題,我嘗試換了一個作業系統,使用Mac 的作業系統,並從原本的32bit變成64bit,其結果不再是出現「out of memory 」,而是跑到一半在程式上出現圖二的狀況,而我找到網路上的資料,也有人出現相同的問題,但結果依然沒變……..
以上是我這次遇到的問題,因為我不是本科系的,可能專業知識還沒這麼強烈,在麻煩大神幫幫忙了,非常感謝🙏
考慮asyncio?
刪除