只要是有研究過使用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的東西
真期待之後完成的那一天
沒有留言:
張貼留言