如何通过 Mechanize 模拟具有 JavaScript 支持的浏览器?

How to emulate a browser with JavaScript support via Mechanize?

我正在使用 Python 脚本 (Mechanize) 登录代理门户。我可以成功登录。我可以从 read() 函数中检查。

但是,登录成功后,我无法访问被代理阻止的站点。所以我检查了来自 FF 的 HTTP headers,发现 Connection: Keep-alive。但是从mechanize,我找到了Connection: close。我尝试使用 browser.addheaders 完全模仿 FF 中的 HTTP header 但这也不起作用:(

深入挖掘后,我发现了一些服务器关闭连接的建议,因为 mechanize 不能完全模拟浏览器,因为网页包含 mechanize

不支持的 JS

那么,有没有办法模拟(让服务器感觉)mechanize 是一个浏览器(支持 JS),即使它不支持?

顺便说一句,我不需要JS,我上面说的可以成功登录。并且请不要推荐 PhantomJS。 我需要一个 Python 包来完成这项工作,而不是无头浏览器。

更新:

FireFox Headers:

GET xxx HTTP/1.1
Host: xxx
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: DSLastAccess=1454082611
Connection: keep-alive


HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: DSEPAgentInstalled=; path=/; expires=Tue, 31-Jan-2006 16:18:32 GMT; secure
Date: Fri, 29 Jan 2016 16:18:32 GMT
x-frame-options: SAMEORIGIN
Connection: Keep-Alive
Keep-Alive: timeout=15
Pragma: no-cache
Cache-Control: no-store
Expires: -1
Transfer-Encoding: chunked

机械化添加headers:

browser.addheaders = [('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'),\
            ('Accept-Language', 'en-US,en;q=0.5'),\
            ('Accept-Encoding', 'gzip, deflate'),\
            ('Host', 'xxx.net'),\
            ('Connection','keep-alive'),\
            ('Cookie', 'DSLastAccess=1454082611'),\
            ('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0')]

机械化Headers

send: 'CONNECT xxx.net:443 HTTP/1.0\r\n'
send: '\r\n'
send: 'GET xxx.cgi HTTP/1.1\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nHost: xxx.net\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0\r\nConnection: close\r\nCookie: DSLastAccess=1454082611\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Type: text/html; charset=utf-8
header: Set-Cookie: DSEPAgentInstalled=; path=/; expires=Tue, 31-Jan-2006 16:31:03 GMT; secure
header: Date: Fri, 29 Jan 2016 16:31:03 GMT
header: x-frame-options: SAMEORIGIN
header: Connection: close
header: Pragma: no-cache
header: Cache-Control: no-store
header: Expires: -1

另一件让我发疯的事情是,从 mechanize 发送的 Connection: close,尽管我已将其设置为 keep-alive,如您所见addheaders

对于linux

最重要的是,我知道有些人不只是想要一个建议来切换到另一个选项。但是,我相信如果您想在登录后完全访问该页面(由于没有 javascript 支持而目前失败),您应该考虑使用 Selenium.

你可以快速地抓住它sudo pip install selenium

访问网页就像声明您的浏览器一样简单,然后告诉您的浏览器转到所需的网页。在这里,我附上了一个基本示例,让您的浏览器转到一个网页,我使用的页面在很大程度上依赖于 javascript:

import selenium
from selenium import webdriver

try:
    browser = webdriver.Firefox()
    browser.get('mikekus.com')
except KeyboardInterrupt:
    browser.quit()

这行得通,因为 selenium 实际上会打开一个浏览器。但是,如果您希望隐藏浏览器,那么您就不必在任务栏中看到它。

我推荐使用 pyvirtualdisplay 的以下设置,它将使用 visible=0 隐藏浏览器。值得注意的是 pyvirtualdisplay 是 Xvfb 的包装器,因此也需要您安装它。你可以通过 sudo apt-get install xvfb:

得到它
import selenium
from selenium import webdriver
from pyvirtualdisplay import Display


try:
    display = Display(visible=0, size=(800, 600))
    display.start()
    browser = webdriver.Firefox()
    browser.get('mikekus.com')

except KeyboardInterrupt:
    browser.quit()
    display.stop()

我会把填写登录表单等留给你,因为如果你阅读文档就很简单了,每个人都应该这样做。 Navigating With Selenium

当然,在您的情况下,您正在尝试访问代理,然后访问另一个站点。此方法意味着您可以通过访问页面上的字段将代理从代理页面本身定向到网页。我敢肯定,稍等片刻,您可以继续导航到多个页面和页面元素,再次进行一些研究。

希望对您有所帮助。祝你好运。