之前使用selenium的無頭瀏覽器,自從phantomjs2016後慢慢不更新了以後,selenium也開始找下家,這時候谷歌的chrome率先搞出來無頭瀏覽器並開放了各類api,隨後firefox也開始作。
如今selenium的測試也都支持這兩個瀏覽器的無頭模式了,只須要在引入的時候配置一下就能夠了。之因此要採用谷歌chrome官方無頭框架puppeteer的python版本pyppeteer,是由於有些網頁是能夠檢測到是不是使用了selenium。而且selenium所謂的保護機制不容許跨域cookies保存以及登陸的時候必須先打開網頁而後後加載cookies再刷新的方式很不友好。python
github地址:https://miyakogi.github.io/pyppeteer/git
pyppeteer這個項目是非官方的,是基於谷歌官方puppeteer的python版本。github
注意:原本chrome就問題多多,puppeteer也是各類坑,加上pyppeteer是基於前者的改編python版本,也就是產生了只要前兩個有一個有bug,那麼pyppeteer就會原封不動的繼承下來,原本這沒什麼,可是如今遇到的問題就是pyppeteer這個項目從18年9月份以後就沒更新過了,前二者都在不斷的更新迭代,而pyppeteer一直不更新,致使不少bug根本沒人修復。web
1)pyppeteer.errors.NetworkError: Protocol error Network.getCookies: Target close
控制訪問指定url以後await page.goto(url),會遇到上面的錯誤,若是這時候使用了sleep之類的延時也會出現這個錯誤或者相似的time out。
這個問題是puppeteer的bug,可是對方已經修復了,而pyppeteer遲遲沒更新,就只能靠本身了,搜了不少人的文章,例如:https://github.com/miyakogi/pyppeteer/issues/171 ,可是我按照這個並無成功。
也有人增長一個函數,但調用這個參數依然沒解決問題。chrome
async def scroll_page(page):
cur_dist = 0
height = await page.evaluate("() => document.body.scrollHeight")
while True:
if cur_dist < height:
await page.evaluate("window.scrollBy(0, 500);")
await asyncio.sleep(0.1)
cur_dist += 500
else:
break
能夠把python第三方庫websockets版本7.0改成6.0就能夠了,親測可用。api
pip uninstall websockets #卸載websockets pip install websockets==6.0 #指定安裝6.0版本
2)chromium瀏覽器多開頁面卡死問題
解決這個問題的方法就是瀏覽器初始化的時候添加’dumpio’:True。跨域
3)瀏覽器窗口很大,內容顯示很小
上面的問題是須要設置瀏覽器顯示大小,默認就是沒法正常顯示。能夠看到頁面左側右側都是空白,網站內容並無完整鋪滿chrome.瀏覽器
browser = await launch({'headless': False,'dumpio':True, 'autoClose':False,'args': ['--no-sandbox', '--window-size=1366,850']}) await page.setViewport({'width':1366,'height':768})
經過上面設置Windows-size和Viewport大小來實現網頁完整顯示。安全
可是對於那種向下無限加載的長網頁這種狀況若是瀏覽器是可見狀態會顯示不全,針對這種狀況的解決方法就是複製當前網頁新開一個標籤頁粘貼進去就正常了websocket
import asyncio from pyppeteer import launch import time async def main():exepath = 'C:/Users/tester02/AppData/Local/Google/Chrome/Application/chrome.exe' browser = await launch({'executablePath': exepath, 'headless': False, 'slowMo': 30}) page = await browser.newPage() await page.setViewport({'width': 1366, 'height': 768}) await page.goto('http://192.168.2.66') await page.type("#Login_Name_Input", "test02") await page.type("#Login_Password_Input", "12345678", ) await page.waitFor(1000) await page.click("#Login_Login_Btn") await page.waitFor(3000) await browser.close() asyncio.get_event_loop().run_until_complete(main())
import asyncio import time from pyppeteer import launch async def gmailLogin(username, password, url): #'headless': False若是想要瀏覽器隱藏更改False爲True # 127.0.0.1:1080爲代理ip和端口,這個根據本身的本地代理進行更改,若是是vps裏或者全局模式能夠刪除掉'--proxy-server=127.0.0.1:1080' browser = await launch({'headless': False, 'args': ['--no-sandbox', '--proxy-server=127.0.0.1:1080']}) page = await browser.newPage() await page.setUserAgent( 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36') await page.goto(url) # 輸入Gmail await page.type('#identifierId', username) # 點擊下一步 await page.click('#identifierNext > content') page.mouse # 模擬真實點擊 time.sleep(10) # 輸入password await page.type('#password input', password) # 點擊下一步 await page.click('#passwordNext > content > span') page.mouse # 模擬真實點擊 time.sleep(10) # 點擊安全檢測頁面的DONE # await page.click('div > content > span')#若是本機以前登陸過,而且page.setUserAgent設置爲以前登陸成功的瀏覽器user-agent了, # 就不會出現安全檢測頁面,這裏若是有須要的本身根據需求進行更改,可是仍是推薦先用經常使用瀏覽器登陸成功後再用python程序進行登陸。 # 登陸成功截圖 await page.screenshot({'path': './gmail-login.png', 'quality': 100, 'fullPage': True}) #打開谷歌全家桶跳轉,以Youtube爲例 await page.goto('https://www.youtube.com') time.sleep(10) if __name__ == '__main__': username = '你的gmail包含@gmail.com' password = r'你的gmail密碼' url = 'https://gmail.com' loop = asyncio.get_event_loop() loop.run_until_complete(gmailLogin(username, password, url)) # 代碼由三分醉編寫,網址www.sanfenzui.com,參考以下文章: # https://blog.csdn.net/Chen_chong__/article/details/82950968