日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python爬虫之pyppeteer的使用(爬虫、获取cookie、截屏插件、防爬绕过)

發布時間:2025/3/15 python 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python爬虫之pyppeteer的使用(爬虫、获取cookie、截屏插件、防爬绕过) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

官方幫助:

  • https://pyppeteer.github.io/pyppeteer/reference.html

?

下載文本中的網頁源碼,由于需要向下拉動滾動條所以使用pyppeteer渲染網頁,并執行js代碼,可是發現開啟無界面的時候似乎執行不了js代碼,還有異步的時候好像也執行不了js代碼

環境部署

pip install

pip install pyppeteer -i https://pypi.douban.com/simple

chromium下載

chromium下載地址:https://npm.taobao.org/mirrors/chromium-browser-snapshots/
下載之后解壓之后,通過executablePath屬性指定運行瀏覽器了

啟動參數:

  • ignoreHTTPSErrors (bool): 是否要忽略 HTTPS 的錯誤,默認是 False。
  • headless (bool): 是否啟用 Headless 模式,即無界面模式,如果 devtools 這個參數是 True 的話,那么該參數就會被設置為 False,否則為 True,即默認是開啟無界面模式的。
  • executablePath (str): 可執行文件的路徑,如果指定之后就不需要使用默認的 Chromium 了,可以指定為已有的 Chrome 或 Chromium。
  • slowMo (int|float): 通過傳入指定的時間,可以減緩 Pyppeteer 的一些模擬操作。
  • args (List[str]): 在執行過程中可以傳入的額外參數。
  • ignoreDefaultArgs (bool): 不使用 Pyppeteer 的默認參數,如果使用了這個參數,那么最好通過 args 參數來設定一些參數,否則可能會出現一些意想不到的問題。這個參數相對比較危險,慎用。
  • handleSIGINT (bool): 是否響應 SIGINT 信號,也就是可以使用 Ctrl + C 來終止瀏覽器程序,默認是 True。
  • handleSIGTERM (bool): 是否響應 SIGTERM 信號,一般是 kill 命令,默認是 True。
  • handleSIGHUP (bool): 是否響應 SIGHUP 信號,即掛起信號,比如終端退出操作,默認是 True。
  • dumpio (bool): 是否將 Pyppeteer 的輸出內容傳給 process.stdout 和 process.stderr 對象,默認是 False。
  • userDataDir (str): 即用戶數據文件夾,即可以保留一些個性化配置和操作記錄。
  • env (dict): 環境變量,可以通過字典形式傳入。
  • devtools (bool): 是否為每一個頁面自動開啟調試工具,默認是 False。如果這個參數設置為 True,那么 headless 參數就會無效,會被強制設置為 False。
  • logLevel (int|str): 日志級別,默認和 root logger 對象的級別相同。
  • autoClose (bool): 當一些命令執行完之后,是否自動關閉瀏覽器,默認是 True。
  • loop (asyncio.AbstractEventLoop): 時間循環對象。
  • Python爬蟲 Pyppeteer 清空input輸入框的值

    • await page.evaluate('document.querySelector("#txt_account").value=""')

常見參數

屬性數據類型描述
executablePathstrchrome.exe運行的路徑
ignorehttpserrrorsbool忽略https錯誤,默認false
headlessboolTrue 開始無頭瀏覽器 False關閉無頭
dumpiobool設置True 解決瀏覽器多開卡死

args的參數設置:

屬性數據類型描述
–disable-infobars-關閉自動化提示框
–window-size=1920,1080str設置瀏覽器大小嗎,1920是寬,1080是寬
–log-level=30str日志保存等級
–start-maximized-窗口最大化模式
–proxy-server=http://localhost:1080str設置代理
userDataDir=D:\userData\str用戶文件保存地址
import asyncio from pyppeteer import launch import re, os,timeasync def create_page():browser = await launch(headless=True, dumpio=True)return browserasync def close_page(browser):await browser.close()async def start(sem, url):# print(url)async with sem: #控制協程的并發量page = await browser.newPage()await page.goto(url)# for i in range(10): # 執行js代碼向下滾動滾動條# dimensions = await page.evaluate(f'var q=document.documentElement.scrollTop={i * 1000}')# await asyncio.sleep(1)# sn = re.search('sn=(.*?)&', url).group(1)# with open(os.path.join(r'E:\study\out', f'{sn}.html'), 'ab') as f:# data = await page.content()# f.write(data.encode('utf8'))print(await page.content())await page.close()if __name__ == '__main__':sem = asyncio.Semaphore(5)fundlist = []path = r'C:\Users\Admin\Desktop\新建 文本文檔.txt'loop = asyncio.get_event_loop() browser = loop.run_until_complete(create_page()) #創建一個瀏覽器對象for line in open(path, 'r'):fundlist.append(line)task = [loop.create_task(start(sem, url)) for url in fundlist]loop.run_until_complete(asyncio.wait(task))loop.run_until_complete(close_page(browser))

使用pyppeteer時有個bug會報錯,將源碼改動下就ok
鏈接:?這里.

launch_kwargs = {# 控制是否為無頭模式"headless": False,# chrome啟動命令行參數"args": [# 瀏覽器代理 配合某些中間人代理使用"--proxy-server=http://127.0.0.1:8008",# 最大化窗口"--start-maximized",# 取消沙盒模式 沙盒模式下權限太小"--no-sandbox",# 不顯示信息欄 比如 chrome正在受到自動測試軟件的控制 ..."--disable-infobars",# log等級設置 在某些不是那么完整的系統里 如果使用默認的日志等級 可能會出現一大堆的warning信息"--log-level=3",# 設置UA"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",],"dumpio":True,# 當界面開多了時會卡住,設置這個參數就不會了# 用戶數據保存目錄 這個最好也自己指定一個目錄# 如果不指定的話,chrome會自動新建一個臨時目錄使用,在瀏覽器退出的時候會自動刪除臨時目錄# 在刪除的時候可能會刪除失敗(不知道為什么會出現權限問題,我用的windows) 導致瀏覽器退出失敗# 然后chrome進程就會一直沒有退出 CPU就會狂飆到99%"userDataDir": "",}

設置viewport 自動獲取當前屏幕大小并設置viewport

# coding:utf8 import asyncio from pyppeteer import launchdef screen_size():"""使用tkinter獲取屏幕大小"""import tkintertk = tkinter.Tk()width = tk.winfo_screenwidth()height = tk.winfo_screenheight()tk.quit()return width, heightasync def main():launch_kwargs = {"headless": False}# 啟動瀏覽器browser = await launch(launch_kwargs)# 打開標簽頁page = await browser.newPage()# 默認 800 * 600 一般是不夠的print(page.viewport)#width, height = screen_size()# 設置網頁可視區域大小await page.setViewport({"width": width,"height": height})await browser.close()returnasyncio.get_event_loop().run_until_complete(main())

導出或加載cookie

# 取出cookiecookies = await page.cookies()# 這里可以做些什么 :)pass# 然后導入cookieawait page.setCookie(*cookies)

?

完整的一個實例

#!/usr/bin/python # -*- coding: UTF-8 -*- """ @time:2020/04/04 """import asyncio import logging import tkinterfrom pyppeteer import launch, launcher from lxml import etreeasync def main():# 瀏覽器 啟動參數start_parm = {# 啟動chrome的路徑"executablePath": r"C:\Users\yq\AppData\Local\pyppeteer\pyppeteer\local-chromium\722234\chrome-win\chrome.exe",# 關閉無頭瀏覽器"headless": False,"args": ['--disable-infobars', # 關閉自動化提示框# '--window-size=1920,1080', # 窗口大小'--log-level=30', # 日志保存等級, 建議設置越好越好,要不然生成的日志占用的空間會很大 30為warning級別'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', # UA'--no-sandbox', # 關閉沙盒模式'--start-maximized', # 窗口最大化模式# '--proxy-server=http://localhost:1080' # 代理r'userDataDir=D:\project_demo\python_demo\spider_demo\JavaScript 逆向系列課\userdata' # 用戶文件地址],}await page.goto('https://www.httpbin.org/headers')page_text = await page.content()input('----------------')await browser.close()asyncio.get_event_loop().run_until_complete(main())

窗口/可視區最大化

但窗口設置最大化(–start-maximized)或窗口大小(–window-size=1920,1080)時,發現自己頁面可視區域沒有變化。成下面圖片顯示效果

設置可視化參數,代碼如下

# !/usr/bin/python # -*- coding: UTF-8 -*- """ @time:2020/04/04 """ import asyncio import tkinterfrom pyppeteer import launcher# 注意 在導入launch之前先把默認參數改了 # 去除自動化 啟動參數 launcher.AUTOMATION_ARGS.remove("--enable-automation") from pyppeteer import launchasync def main():# 瀏覽器 啟動參數start_parm = {# 啟動chrome的路徑"executablePath": r"C:\Users\yq\AppData\Local\pyppeteer\pyppeteer\local-chromium\722234\chrome-win\chrome.exe",# 關閉無頭瀏覽器"headless": False,"args": ['--disable-infobars', # 關閉自動化提示框'--no-sandbox', # 關閉沙盒模式'--start-maximized', # 窗口最大化模式],}browser = await launch(**start_parm)page = await browser.newPage()# 查看當前 桌面視圖大小tk = tkinter.Tk()width = tk.winfo_screenwidth()height = tk.winfo_screenheight()tk.quit()print(f'設置窗口為:width:{width} height:{height}')# 設置網頁 視圖大小await page.setViewport(viewport={'width': width, 'height': height})await page.goto('https://www.baidu.com')input('----------------')await browser.close()asyncio.get_event_loop().run_until_complete(main())

隱藏瀏覽器特征

pyppeteer跟selenium一樣會有瀏覽器特征,所以需要修改,隱藏特征防止被識別。
主要有下面兩點:

  • 去除瀏覽器自動化參數?--enable-automation
  • 去除window.navigator.webdriver等檢測
  • #!/usr/bin/python # -*- coding: UTF-8 -*- """ @time:2020/04/04 """import asyncio import logging import tkinterfrom pyppeteer import launcher # 第一步 去除瀏覽器自動化參數 # 必須在 from pyppeteer import launch 前去除參數 # 去除自動化 啟動參數 launcher.AUTOMATION_ARGS.remove("--enable-automation")from pyppeteer import launch from lxml import etreeasync def main():# 瀏覽器 啟動參數start_parm = {# 啟動chrome的路徑"executablePath": r"C:\Users\yq\AppData\Local\pyppeteer\pyppeteer\local-chromium\722234\chrome-win\chrome.exe",# 關閉無頭瀏覽器"headless": False,"args": ['--disable-infobars', # 關閉自動化提示框# '--window-size=1920,1080', # 窗口大小'--log-level=30', # 日志保存等級, 建議設置越好越好,要不然生成的日志占用的空間會很大 30為warning級別'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', # UA'--no-sandbox', # 關閉沙盒模式'--start-maximized', # 窗口最大化模式# '--proxy-server=http://localhost:1080' # 代理r'userDataDir=D:\project_demo\python_demo\spider_demo\JavaScript 逆向系列課\userdata' # 用戶文件地址],}browser = await launch(**start_parm)page = await browser.newPage()tk = tkinter.Tk()width = tk.winfo_screenwidth()height = tk.winfo_screenheight()tk.quit()await page.setViewport(viewport={'width': width, 'height': height})# 第二步,修改 navigator.webdriver檢測# 其實各種網站的檢測js是不一樣的,這是比較通用的。有的網站會檢測運行的電腦運行系統,cpu核心數量,鼠標運行軌跡等等。# 反爬jsjs_text = """ () =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } });window.navigator.chrome = { runtime: {}, };Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], });}"""await page.evaluateOnNewDocument(js_text) # 本頁刷新后值不變,自動執行jsawait page.goto('https://www.httpbin.org/headers')page_text = await page.content()print(page_text)input('==========')await browser.close()asyncio.get_event_loop().run_until_complete(main())

    攔截請求

    可以對出現的請求,進行攔截 類似mitmproxy。

    #!/usr/bin/python # -*- coding: UTF-8 -*- """ @time:2020/04/04 """import asyncio import jsonfrom jsonpath import jsonpath from pyppeteer import launcherlauncher.AUTOMATION_ARGS.remove("--enable-automation")from pyppeteer import launchfrom pyppeteer.network_manager import Request, Responseasync def intercept_request(req:Request):await req.continue_() # 請求,看源碼可以重新編寫請求async def intercept_response(res:Response):if 'ext2020/apub/json/prevent.new' in res.url:print('攔截到請求')json_text = await res.text()title_li = jsonpath(json.loads(json_text), '$..title')for title in title_li:print(title)passasync def main():# 瀏覽器 啟動參數start_parm = {# 啟動chrome的路徑"executablePath": r"C:\Users\yq\AppData\Local\pyppeteer\pyppeteer\local-chromium\722234\chrome-win\chrome.exe",# 關閉無頭瀏覽器 默認是無頭啟動的"headless": False,"args": ['--disable-infobars', # 關閉自動化提示框# '--no-sandbox', # 關閉沙盒模式'--start-maximized', # 窗口最大化模式'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',# UA],}# 創建瀏覽器對象,可以傳入 字典形式參數browser = await launch(**start_parm)# 創建一個頁面對象, 頁面操作在該對象上執行page = await browser.newPage()await page.setJavaScriptEnabled(enabled=True)# 啟用攔截器await page.setRequestInterception(True)page.on('request', intercept_request) page.on('response', intercept_response)js_text = """() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } });window.navigator.chrome = { runtime: {}, };Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], });}"""await page.evaluateOnNewDocument(js_text) # 本頁刷新后值不變,自動執行jsawait page.goto('https://news.qq.com/') # 頁面跳轉await browser.close()asyncio.get_event_loop().run_until_complete(main()) # 創建異步池并執行main函數。

    按鈕路徑獲取(page.click)

    谷歌瀏覽器 -> copy -> copy js path

    獲取驗證碼

    新建瀏覽器,進行登錄,由于驗證碼的識別準確率不是百分之百,需要多次嘗試。

    async def main(self, username, pwd, url): # 定義main協程函數,login_count = 0# 打開瀏覽器browser = await launch({'headless': False, "userDataDir": r"./temp_data", 'args': ['--no-sandbox'], })# 登錄檢測while login_count < 10:# 登錄await self.login(browser, username, pwd, url)# 檢測是否登錄成功if await self.check_login(browser):breakelse:login_count += 1# 嘗試登錄次數大于10就退出if login_count > 10:print("login failed!")await browser.close()returndo_something()await browser.close()

    可以替換程序中驗證操作函數,實現不同的驗證方式。
    其中提交過程采用了xpath定位提交按鈕。

    async def login(self, browser, username, pwd, url):page = await browser.newPage() # 啟動個新的瀏覽器頁面await page.setUserAgent('Mozilla/5.0 (Windows NT 6.1; WOW64) ''AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/68.0.3440.106 Safari/537.36')await page.goto(url) # 訪問登錄頁面# 就是在瀏覽器運行的時候,始終讓window.navigator.webdriver=false# navigator是windiw對象的一個屬性,同時修改plugins,languages,navigator 且讓await page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')# 以下為插入中間js,將淘寶會為了檢測瀏覽器而調用的js修改其結果。await page.evaluate('''() =>{ window.navigator.chrome = { runtime: {}, }; }''')await page.evaluate('''() =>{ Object.defineProperty(navigator,'languages', { get: () => ['en-US', 'en'] }); }''')await page.evaluate('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')time.sleep(2)# 使用type選定頁面元素,并修改其數值,用于輸入賬號密碼,修改的速度仿人類操作,因為有個輸入速度的檢測機制# 因為 pyppeteer 框架需要轉換為js操作,而js和python的類型定義不同,所以寫法與參數要用字典,類型導入await page.type('#username', username, {'delay': self.input_time_random() - 50})await page.type('#password', pwd, {'delay': self.input_time_random()})# await page.screenshot({'path': './picture/headless-test-result.png'}) # 截圖測試time.sleep(1)# 驗證碼操作verification_code(page);# 點擊提交submit = await page.xpath("//button[@class='auth_login_btn primary full_width']")await submit[0].click()time.sleep(1)

    驗證碼識別和輸入

    我在這里利用了某網站的驗證碼識別api,通過http方式就能上傳驗證碼圖片,并獲取驗證碼。這個網站每天有固定的1000張圖片免費次數,足夠我們使用。第一個請求鏈接的用戶名和密碼換成我們注冊該網站的用戶名和密碼即可。具體可以看官方的API文檔。
    該網站地址:http://fast.95man.com/

    # 驗證碼登錄async def verification_code(self, page):await page.waitFor(5 * 1000) # 等待驗證碼圖片加載yazhengma = await page.waitForSelector('#captchaImg') # 定位驗證碼元素await yazhengma.screenshot({'path': './picture/yazhengma.png'}) # 保存驗證碼圖片# 獲取驗證碼code = self.get_code('./picture/yazhengma.png')# 輸入驗證碼await page.type('#captchaResponse', code, {'delay': self.input_time_random()})def get_code(self, file_path):# 以下為GET請求url = 'http://api.95man.com:8888/api/Http/UserTaken?user=username&pwd=password&isref=0'token_request = requests.get(url)token_raw = str(token_request.content)# 切片獲取tokentoken = token_raw[4: -1]print(token)# 發送圖片解析請求url = "http://api.95man.com:8888/api/Http/Recog?Taken=" + token + "&imgtype=1&len=4"file_path = file_pathfiles = {'file': open(file_path, 'rb')}# 上傳圖片r = requests.post(url, files=files)print(r.url, r.text)# 切片獲取驗證碼return r.text[6:10]

    ?

    防檢測的一些方法

    1、常用小功能

    async def init_pyppeteer(self):self.browser = await pyppeteer.launch({'headless': False,# 'userDataDir': './userdata',# 用戶臨時目錄,保存cookie可以開啟'args': [# '--window-size={1300},{800}','--start-maximized', # 最大化窗口'--proxy-server=http://118.24.51.247:1443',#瀏覽器代理 配合某些中間人代理使用# '--load-extension={}'.format(chrome_extension), # 加載插件# '--disable-extensions-except={}'.format(chrome_extension),# '--disable-extensions','--hide-scrollbars','--disable-bundled-ppapi-flash','--mute-audio','--no-sandbox', # 取消沙盒模式 沙盒模式下權限太小'--no-sandbox', # 不顯示信息欄 比如 chrome正在受到自動測試軟件的控制'--disable-setuid-sandbox','--disable-gpu','--disable-infobars'# log等級設置 在某些不是那么完整的系統里 如果使用默認的日志等級 可能會出現一大堆的warning信息],'dumpio': True, # 減少內存消耗# "slowMo": 25 # 讓執行慢下來})self.page = await self.browser.newPage()width, height = self.screen_size()await self.page.setViewport({"width": width,"height": height})# 設置瀏覽器頭部await self.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299')await self.page.evaluateOnNewDocument('() =>{ Object.defineProperties(navigator,''{ webdriver:{ get: () => false } }) }') # 本頁刷新后值不變

    1.1、繞過對方網站監測

    import pyppeteer async def page_evaluate(self, page):'''window.navigator.webdriver=false'''await page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => undefined } }) }''') # 以下為插入中間js,將淘寶會為了檢測瀏覽器而調用的js修改其結果。await page.evaluate('''() =>{ window.navigator.chrome = { runtime: {}, }; }''')await page.evaluate('''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')await page.evaluate('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')async def main(self):browser = await pyppeteer.launch()page = await browser.newPage()await self.page_evaluate(page)

    1.2、網絡通信異常處理

    await page.goto(h5_detail_url,waitUntil=["networkidle0", "load", "domcontentloaded"],options={'timeout': 30000})

    1.3、禁止渲染

    # # 是否啟用JS,enabled設為False,則無渲染效果 await self.page.setJavaScriptEnabled(enabled=False)

    1.4、等待元素加載

    #waitForSelector 默認為30000(30秒),為0禁用超時 await self.page.waitForSelector('.shop_list .clearfix span.tit_shop',{'timeout': 9000}) #等待元素加載 await asyncio.sleep(2)

    1.5、滾動瀏覽器

    使用js滾動到某個元素

    # 使用js滾動到某個元素 await self.page.evaluate('document.querySelector(".page_al").scrollIntoView();')

    滾動到瀏覽器底部

    #滾動到瀏覽器底部 await self.page.evaluate('window.scrollBy(0, document.body.scrollHeight)')

    滾動多少像素

    #瀏覽器向上滾動400個像素 await self.page.evaluate('window.scrollBy(0,-400)')

    ?

    總結

    以上是生活随笔為你收集整理的Python爬虫之pyppeteer的使用(爬虫、获取cookie、截屏插件、防爬绕过)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。