【问题标题】:How to emulate a browser with JavaScript support via Mechanize?如何通过 Mechanize 模拟支持 JavaScript 的浏览器?
【发布时间】:2016-05-04 13:53:50
【问题描述】:

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

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

经过深入研究,我发现了一些服务器关闭连接的建议,因为机械化无法完全模拟浏览器,因为网页包含mechanize不支持的JS

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

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

更新:

FireFox 标头:

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

机械化 addheaders:

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')]

机械化标头

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 中看到的那样

【问题讨论】:

  • HTTP 标头中没有关于 JS 的内容。 Keep-alive 在这里可能无关紧要。您可能应该在工作版本和非工作版本中发布 HTTP 标头(请求和响应)。编辑会话 cookie 或其他内容,但检查它是否存在。
  • @SergeySalnikov,感谢您的回复。我并不是说 HTTP 标头中有关于 JS 的内容。我只是说从 HTTP 标头中我可以看出服务器关闭了连接。这可能是因为服务器可以判断mechanize 不是浏览器。它可以说是因为它没有看到对 JS 的支持。所以它将mechanize 识别为不是浏览器
  • 你的意思是服务器关闭连接没有任何回复?
  • @SergeySalnikov,当然不会。我的意思是当我检查服务器 HTTP 标头时,它有 Connection: close
  • 据我所知,HTTP 服务器无法检测到客户端 JavaScript 支持。检测客户端最常见的方法是通过 User-Agent 标头属性。如果您按照@SergeySalnikov 的建议发布请求/响应标头,那就太好了

标签: javascript python mechanize user-agent keep-alive


【解决方案1】:

对于 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

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

我希望这会有所帮助。祝你好运。

【讨论】:

  • 感谢您的详细回答。实际上,我已经在使用SeleniumXVFB。但由于某种原因,我不能将它们用于发布的问题。我只需要用mechanize 解决问题,再次感谢
  • 是什么让您无法使用它们?如果可以的话,您使用的是什么代理?也许我可以为你做一些测试
  • 经过进一步调查,您无法使用 mechanize 访问 javascript,但是,如 (stackoverflow.com/questions/802225/…) 中所述,如果您将 user_agent 设置为较旧的浏览器,您可能可以通过但没有的JavaScript。祝你好运。
  • 1black1,谢谢你的回答,看起来很有希望:) 我会试试这个旧浏览器的东西,如果它有效,我会告诉你它是否有效,所以你把它作为答案发布,你就会得到赏金: ) .但这可能是在星期一,因为我现在要离开办公室
  • 1black1,添加旧的 UserAgent 不起作用。正如@Sergey Salnikov 所建议的那样,看起来机械化永远无法拥有keep-alive 连接。然后我只剩下Xvfb的选项了
猜你喜欢
  • 1970-01-01
  • 2016-09-26
  • 2018-01-10
  • 2011-07-03
  • 1970-01-01
  • 2014-03-13
  • 2011-02-20
  • 1970-01-01
  • 2011-01-05
相关资源
最近更新 更多