机械化:要解压的值太多(预期为 2)

Mechanize: too many values to unpack (expected 2)

我尝试编写以下代码,我正在尝试在 Python 3.7 中编写一个代码,它只打开一个网络浏览器,并在 Command Line 中提供给它的网站:

Example.py

import sys

from mechanize import Browser
browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# pretend you are a real browser
browser.addheaders = [('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

listOfSites = sys.argv[1:]
for i in listOfSites:
    browser.open(i)

我在cmd中输入了以下命令:

python Example.py https://www.google.com

我有以下回溯:

Traceback (most recent call last):
  File "Example.py", line 19, in <module>
    browser.open(i)
  File "C:\Python37\lib\site-packages\mechanize\_mechanize.py", line 253, in open
    return self._mech_open(url_or_request, data, timeout=timeout)
  File "C:\Python37\lib\site-packages\mechanize\_mechanize.py", line 283, in _mech_open
    response = UserAgentBase.open(self, request, data)
  File "C:\Python37\lib\site-packages\mechanize\_opener.py", line 188, in open
    req = meth(req)
  File "C:\Python37\lib\site-packages\mechanize\_urllib2_fork.py", line 1104, in do_request_
    for name, value in self.parent.addheaders:
ValueError: too many values to unpack (expected 2)

我对 Python 很陌生。这是我在这里的第一个代码。我坚持上面的回溯,但还没有找到解决方案。我也在 SO 社区上搜索了很多问题,但它们似乎没有帮助。接下来我该做什么?

更新:

按照@Jean-François-Fabre的建议,在他的回答中,我在header中添加了'User-agent',现在没有回溯,但仍然存在是我的 link 无法在浏览器中打开的问题。

这是 addheader 现在的样子:

browser.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

我根本不知道 mechanize,但追溯和变量名称(以及一些谷歌搜索)可以提供帮助。

您正在使用字符串列表初始化 addheaders。其他一些示例(例如:Mechanize Python and addheader method - how do I know the newest headers?)显示了一个 tuple 的列表,这似乎与回溯相匹配。例如:

browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]

所以它在循环

中正确解压缩到 namevalue
for name, value in whatever.addheaders:

您必须添加 'User-agent' 属性 名称(除了浏览器名称,您还可以传递其他不常用的参数)

即使上述问题仍然存在,我也刚刚找到了解决此问题的方法。我发布这个只是为了让读者知道我们也可以这样做:

不使用mechanize包,我们可以使用webbrowser包,在Example.py[=中写入如下python代码24=]:

import webbrowser
import sys

#This is an upgrade suggested by @Jean-François Fabre
listOfSites = sys.argv[1:]

for i in listOfSites:
    webbrowser.open_new_tab(i)

然后我们可以运行这个python代码通过在terminal/command提示符下执行下面的命令:

python Example.py https://www.google.com https://www.bing.com

上面示例中提到的这个命令将同时打开两个站点。一个是Google,另一个是Bing

同上。猜猜我在深入研究之前没有阅读所有答案。大声笑

import sys
import webbrowser

from mechanize import Browser
browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# pretend you are a real browser
browser.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36')]

listOfSites = sys.argv[1:]
for i in listOfSites:
    webbrowser.open(i)

让我尝试部分回答您的问题:

  • 您添加 "Browser Headers" 是正确的。许多服务器可能会彻底断开您的连接,因为这是被机器人抓取的明确标志。

  • mechanizedocs "is a tool for programmatic web browsing".
    这意味着它主要用于抓取网页、解析其内容、填写表单、点击事物、发送请求,但不使用 "real" 网络浏览器,具有 CSS 渲染等部分。例如,您无法打开页面并截取屏幕截图,因为没有东西 "rendered",要实现此目的,您需要保存页面,并使用其他解决方案呈现它。

  • 如果这符合您的需要,请检查 headless browsers as a technology, there are a lot of them. In the Python ecosystem, other than mechanize, I'd check "headless chromium", as "phantomjs" 很遗憾已停产。

但是如果我没理解错的话,你需要实际的网络浏览器才能打开网页,对吧?出于这个原因,您实际上需要系统中的浏览器来处理这个问题!

案例 1:使用您本机系统的浏览器

找出浏览器的可执行文件在系统中的位置。例如,我的 Firefox 可执行文件位于 "C:\Program Files\Mozilla Firefox\firefox.exe"add it to your PATH.

当您使用 Windows 时,使用开始菜单导航至 Advanced System Settings --> Advanced --> Environment Variables,并将以上路径添加到您的 PATH 变量。

如果您正在使用 Linux export PATH=$PATH:"/path/to/your/browser" 会处理这些事情。

然后,您的代码可以 运行 和

一样简单
import subprocess
import sys

listOfSites = sys.argv[1:]
links = ""
for i in listOfSites:
    links += "-new-tab " + i
print(links)
subprocess.run(["firefox", links])

Firefox 将打开新的 windows,为您提供的每个链接打开一个。

案例 2:使用硒

然后是Selenium,我认为这是解决浏览器相关问题的最成熟的解决方案,也是大多数人使用的。我已经在生产环境中使用它并取得了很好的效果。它既提供呈现网页的浏览器 UI/frontend,又允许您以编程方式处理这些网页。

它需要一些设置,(例如,如果您使用的是 Firefox,则需要从他们的 releases page 下载 geckodriver 可执行文件,然后将其添加到您的 PATH 再次变量。

然后定义您的网络驱动程序,为您需要访问的每个网站和 get 网页生成一个。您也可以截图,作为页面已正确呈现的证明。

from selenium import webdriver
import sys

listOfSites = sys.argv[1:]
for i in listOfSites:
    driver = webdriver.Firefox()
    driver.get('http://'+i)
    driver.save_screenshot(i+'-screenshot.png')

# When you're finished
# driver.quit()

我已经测试了这两个代码片段,它们按预期工作。请让我知道所有这些听起来如何,如果您需要更多信息……! ^^

给你:)

import sys
from mechanize import Browser, Request


browser = Browser()

browser.set_handle_equiv(True)
browser.set_handle_gzip(True)
browser.set_handle_redirect(True)
browser.set_handle_referer(True)
browser.set_handle_robots(False)

# setup your header, add anything you want
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1', 'Referer': 'http://whateveritis.com'}


url_list = sys.argv[1:]
for url in url_list:
    request = Request(url=url, data=None, headers=header)
    response = browser.open(request)
    print(response.read())
    response.close()