Python爬虫(五)关于headless浏览器被反爬虫禁止访问
有些网站会有反爬虫的机制。反爬虫的机制有很多种,之后会在一篇文章中统一说明。
这篇文章是记录headless浏览器时被识别为爬虫的解决方式。
比如这个网站会检查访问者是否异常:"https://haveibeenpwned.com/".
当用PhantomJS或者headless chrome时,只是获取html也会被禁止。如下。
# use PhantomJS
from selenium import webdriver
driver = webdriver.PhantomJS("./phantomjs")
driver.get("https://haveibeenpwned.com/")
html = driver.page_source
print(html)
driver.quit()
# use headless chrome
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("https://haveibeenpwned.com/")
html = driver.page_source
print(html)
driver.quit()
会看到如下错误的输出,无法显示正常页面的html信息。
而用非headless的Chrome时则获取正常。
搜索后发现时因为添加了"--headless"后,在浏览器navigator对象的属性就一定会包含"webdriver: true",很可能是这里被检查到然后被禁止了。但是不用headless还不如直接用浏览器打开,在服务器上运行并不方便。
而PhantomJS是本身的属性就很单一,不能像用浏览器访问时带有足够合理的request header。
解决方式如下,一是用headless firefox。
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
firefox_options = Options()
firefox_options.set_headless()
firefox_options.add_argument('--disable-gpu')
driver = webdriver.Firefox(firefox_options=firefox_options)
driver.get("https://haveibeenpwned.com/")
html = driver.page_source
print(html)
driver.quit()
二是使用自定义header来启动PhantomJS。
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:73.0) Gecko/20100101 Firefox/73.0',
'Connection': 'keep-alive'
}
cap = DesiredCapabilities.PHANTOMJS.copy()
for key, value in headers.items():
cap['phantomjs.page.customHeaders.{}'.format(key)] = value
driver = webdriver.PhantomJS("./phantomjs", desired_capabilities=cap)
driver.get("https://haveibeenpwned.com/")
html = driver.page_source
print(html)
driver.quit()
此时便返回了正常的结果。