Puppeteer 不重啓如何更換代理 IP
攝影:產品經理
豉油雞
我們知道,在寫爬蟲的過程中,如果總是使用同一個 IP,很容易就會被網站識別並封禁,所以需要使用代理 IP 並經常更換。
但如果你在網上搜索 Puppeteer 如何更換代理 IP,你會發現,網上的解決方案一般是這樣寫的:
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({
args: [ '--proxy-server=123.45.67.89:8888' ]
});
const page = await browser.newPage();
await page.goto('http://httpbin.org/ip');
await browser.close();
})();
這種寫法有一個問題,如果你要更換 IP,必須重啓爬蟲。那麼有沒有辦法不重啓爬蟲也能更換代理 IP 呢?
方法有,並且有兩個。
隧道代理
對一些網站來說,只要每次訪問的 IP 不一樣就可以避免被封禁,那麼我們可以使用隧道代理。隧道代理供應商會給我們提供一個唯一的域名和端口。我們把它設置爲爬蟲的代理就可以了。代理供應商會在後端自動給每一次請求更換 IP,不用我們來操心。
我們使用青果雲 [1] 的隧道代理來做演示。它可以免費試用 2 小時。我獲取到的代理 IP 地址爲:http://D5A913AF:B1DE2C46D321@tunnel.qg.net:11151
。於是,我可以修改上面的 Puppeteer 代碼中的 IP 地址:
const puppeteer = require('puppeteer-core');
(async() => {
const browser = await puppeteer.launch({
args: [ '--proxy-server=tunnel.qg.net:11151' ], headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'});
const page = await browser.newPage();
await page.authenticate({username: '賬號', password: '密碼'}); // 如果代理沒有權限驗證,可以移除這一行
response = await page.goto('http://httpbin.org/ip');
console.log('第一次訪問: ', await response.text());
response = await page.goto('http://httpbin.org/ip');
console.log('第二次訪問: ', await response.text());
})()
運行效果如下圖所示:
動態按需修改代理 IP
IP 並不是換得越頻繁越好。如果網站需要登錄,那麼你登錄以後每一次請求都更換 IP,這反而會弄巧成拙,讓網站更加懷疑你是不是爬蟲。還有一些網站,例如淘寶,當你訪問一個頁面的時候,它會自動 301 跳轉多次。在這幾次跳轉的時候,你必須保持 IP 一致,否則它就會屏蔽你。
我們有時候需要實現按需更換代理 IP——讓開發者在需要更換 IP 的時候,再來更換。
爲了讓 Puppeteer 實現這個目標,我們可以安裝一個第三方模塊:puppeteer-page-proxy
:
npm i puppeteer-page-proxy
安裝完成以後,我們來使用看看:
const puppeteer = require('puppeteer-core')
const useProxy = require('puppeteer-page-proxy')
puppeteer.launch({headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'}).then(
async browser => {
console.log('start...')
const page = await browser.newPage()
await useProxy(page, 'http://賬號:密碼@119.5.228.105:21477')
console.log('change proxy success, start to visit url')
resp = await page.goto('http://httpbin.org/ip')
console.log(await resp.text())
await useProxy(page, 'http://賬號:密碼@119.41.199.19:56214')
console.log('change proxy success, start to visit url')
resp = await page.goto('http://httpbin.org/ip')
console.log(await resp.text())
}
)
運行效果如下圖所示:
當我們需要更換 IP 的時候,只需要在代碼裏面執行await useProxy(page, 'http://賬號:密碼@IP:端口')
,就可以更換新的 IP 了。如果你的代理 IP 沒有賬號密碼,那麼可以把代碼改成:await useProxy(page, 'http://IP:端口')
。
可能有人會問,你上面的示例代碼中,你是直接把代理填寫到代碼裏面的。如果我需要訪問某個 URL 來獲取新的代理怎麼辦呢?其實這也很簡單,你可以再安裝一個第三方模塊:axios
用來發起網絡請求獲取新的代理 IP,然後再替換:
npm i axios
還是以青果雲的短效代理 IP 爲例,它可以提供一個接口,訪問接口後,你能得到一個有效期 5-15 分鐘的短效 IP,如下圖所示:
開通試用賬號以後,你可以獲得一個提取代理的 URL,類似於下面這樣:
https://proxy.qg.net/extract?Key=ABCDEFGH&Num=1&AreaId=&Isp=&DataFormat=txt&DataSeparator=%5Cn&Detail=0
訪問以後就能拿到代理 IP,如下圖所示:
現在,我們要在 Puppeteer 裏面,先訪問這個 URL 獲取代理,再把代理 IP 設置到 Puppeteer 中,然後再訪問目標網頁。對應的代碼如下:
const puppeteer = require('puppeteer-extra')
const useProxy = require('puppeteer-page-proxy')
const axios = require('axios')
async function set_proxy(page){
resp = await axios.get('https://proxy.qg.net/extract?Key=ABCDEFG&Num=1&AreaId=&Isp=&DataFormat=txt&DataSeparator=%5Cn&Detail=0')
proxy = 'http://賬號:密碼@' + resp.data
console.log('獲取到的代理 IP 爲:', proxy)
await useProxy(page, proxy)
}
puppeteer.launch({headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'}).then(
async browser => {
console.log('start...')
const [page] = await browser.pages()
await set_proxy(page)
console.log('change proxy success, start to visit url')
resp = await page.goto('http://httpbin.org/ip')
console.log(await resp.text())
}
)
運行效果如下圖所示:
參考文獻
[1] 青果雲: https://www.qg.net/business/proxyip/42.html
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/6PtJtG0FVJV1mBG8eR0WJg