只要是有研究過使用Python的爬蟲程式的話
這兩個應用名稱應該是熟到不行了
這次剛好先後用上,所以做個筆記
為什麼是先後呢?
因為之前某隻程式是用urllib3寫的
在問過AI後,得到這函式無法管理cookies
它推薦使用request裡的session進行連線與管理
並且在我輸入舊程式碼後,幫我替換掉舊的函式庫引入與寫法
太棒了,太懶人了
科技進步萬歲
使用requests裡session的流程很簡單
先建立headers準備騙伺服器說是瀏覽器的連線
再來就是要登入資料,使用者名稱,密碼
然後建立session並預先載入headers,這樣就不用每次傳資料還要載入
接著檢查有沒有上次cookies,有就載入
載入後,連線測試,如果成功,就跳出
如果失敗,就砍掉舊cookie,然後使用帳號密碼登入
登入後,確認成功就把cookies存下來
然後回報成功
確認登入後,接下來就可以取得裡面的網頁資料
然後丟到html parser裡面解析出想要的資料
程式碼的範本如下:
from bs4 import BeautifulSoup
import requests
import pickle
import os
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
}
# 請替換為實際網址
login_url="登入用網址"
target_url="目標網址"
# cookies 文件路徑
cookies_file = "cookies"
# 登入憑證(請替換為真實用戶名和密碼)
payload = {
"Username": "使用者名稱",
"Password": "密碼"
}
#建立session
session = requests.Session()
#將headers載入session中
session.headers.update(headers)
try:
# 檢查 cookies 文件是否存在
if os.path.exists(cookies_file):
print("找到 cookies 文件,嘗試讀取 cookies")
with open(cookies_file, "rb") as f:
session.cookies.update(pickle.load(f))
print(f"Cookies 已從 {cookies_file} 讀取")
# 進一步檢查讀取cookies後可否登入
# 如果前面session沒有用update(headers),這邊get就要補, headers=headers)
response = session.get(target_url)
if not (response.status_code == 200):
#清除session的cookies
session.cookies.clear()
#刪除cookies檔案
os.remove(cookies_file)
if not os.path.exists(cookies_file):
print("未找到 cookies 文件,執行登入")
# 執行登入
# 如果前面沒有用update(headers),這邊post還要補, headers=headers)
response = session.post(login_url, data=payload)
if not (response.status_code == 200):
raise Exception("初始登入失敗,程式終止")
# 保存 cookies
with open(cookies_file, "wb") as f:
pickle.dump(session.cookies, f)
print(f"Cookies 已保存到 {cookies_file}")
# 正式讀取目標網頁
# 如果前面session沒有用update(headers),這邊get就要補, headers=headers)
response = session.get(target_url)
# 把網頁丟入解析器中
parser = BeautifulSoup(response.text, "html.parser")
except Exception as e:
print(f"發生錯誤:{e}")
是不難,而且請AI替換超快的,根本不用我動手
同時,它還會教我一些應用與注意事項
現在學程式真方便啊
不過,問AI還是沒有百分之百正確
上面是沒問題的
可是延著這個對話再問下去,它就給了錯誤的答案了
我有另一個工具程式也是用urllib3寫
然後當時是用異步的寫法下去運作的
所以我就問AI,那異步應用上使用requests的寫法
(其實,我試過原寫法直接替換就可以用了,不過我還是好奇問一下)
然後AI就推了aiohttp這個異步專用的函式庫
並說明,因為原生就使用異步會比使用非異步寫法的requests好,所以建議替換掉
好吧,要換就換,反正是AI換
但是替換時就出問題了
原本requests的cookies,之前範例是用pickle函式庫儲存,然後用update_cookies讀取
然後aiohttp照抄用pickle儲存時就出問題了
pickle在dump這個cookie_jar時,因為格式不對,所以不給存,產生了一個空檔案
而讀取時,雖然不確定正常能不能成功,但這裡絕對失敗,因為讀了一個空的檔案
唉~~果然不能全信
直接用google查aiohttp裡cookie_jar的API,原來自己就有save與load功能
靠,那還用什麼pickle,直接cookie_jar.load(PATH)跟cookie_jar.save(PATH)就好
所以上面的程式碼用aiohttp改寫後正確版本如下:
from bs4 import BeautifulSoup
import aiohttp
#import pickle #不需要pickle了
import os
import asyncio #導入異步用函式庫
async def main():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
}
# 請替換為實際網址
login_url="登入用網址"
target_url="目標網址"
# cookies 文件路徑
cookies_file = "cookies"
# 登入憑證(請替換為真實用戶名和密碼)
payload = {
"Username": "使用者名稱",
"Password": "密碼"
}
#建立session,並將headers載入session中
async with aiohttp.ClientSession(headers=headers) as session:
try:
# 檢查 cookies 文件是否存在
if os.path.exists(cookies_file):
print("找到 cookies 文件,嘗試讀取 cookies")
session.cookie_jar.load(cookies_file)
print(f"Cookies 已從 {cookies_file} 讀取")
# 進一步檢查讀取cookies後可否登入
# 如果前面沒有引入headers,這邊get還要補, headers=headers)
async with session.get(target_url) as response:
if not (response.status == 200):
#清除session的cookies
session.cookie_jar.clear()
#刪除cookies檔案
os.remove(cookies_file)
if not os.path.exists(cookies_file):
print("未找到 cookies 文件,執行登入")
# 執行登入
# 如果前面沒有引入headers,這邊post還要補, headers=headers)
async with session.post(login_url, data=payload) as response:
if not (response.status == 200):
raise Exception("初始登入失敗,程式終止")
# 保存 cookies
session.cookie_jar.save(cookies_file)
print(f"Cookies 已保存到 {cookies_file}")
# 正式讀取目標網頁
# 如果前面沒有引入headers,這邊get還要補, headers=headers)
async with session.get(target_url) as response:
# 使用response.text()讀取網頁內谷
html_content = await response.text()
# 把網頁丟入解析器中
parser = BeautifulSoup(html_content, "html.parser")
except Exception as e:
print(f"發生錯誤:{e}")
# 使用異步執行程式
asyncio.get_event_loop().run_until_complete(main())
現在AI寫程式真的超方便的
有一個陳年老計畫看來可以挖出來實現了
雖然現在已經沒有當年的實值效益了
不過至少懸掛多年的待辦清單可以再清掉一項
不,應該說再完成一項,自己DIY的東西
真期待之後完成的那一天
沒有留言:
張貼留言