python:如何在mechanize中使用/更改代理

0 投票
1 回答
2494 浏览
提问于 2025-04-18 17:52

我正在用Python写一个网页抓取程序,使用的是mechanize库。现在遇到的问题是,我抓取的网站限制了你在网站上停留的时间。以前我手动操作的时候,会用SOCKS代理来绕过这个限制。

我尝试去网络设置(我用的是Macbook Pro Retina 13',系统是Mavericks)更改代理设置。但是程序并没有响应这个更改,还是继续运行,没有使用代理。

于是我添加了.set_proxies(),现在打开网站的代码大概是这样的:

b=mechanize.Browser()                               #open browser
b.set_proxies({"http":"96.8.113.76:8080"})          #proxy
DBJ=b.open(URL)                                     #open url

当我运行程序时,出现了这个错误:

Traceback (most recent call last):
 File "GM1.py", line 74, in <module>
   DBJ=b.open(URL)                  
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_mechanize.py", line 203, in open
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_mechanize.py", line 230, in _mech_open
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_opener.py", line 193, in open
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_urllib2_fork.py", line 344, in _open
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_urllib2_fork.py", line 332, in _call_chain
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_urllib2_fork.py", line 1142, in http_open
 File "build/bdist.macosx-10.9-intel/egg/mechanize/_urllib2_fork.py", line 1118, in do_open
urllib2.URLError: <urlopen error [Errno 54] Connection reset by peer>

我猜测代理已经更改了,而这个错误是因为代理的问题。

也许我对.set_proxies()的使用不太对。

我不确定是代理本身有问题,还是连接速度真的很慢。

我应该使用SOCKS代理来做这种事情吗?还是说有更好的选择来实现我想做的事情?

任何信息都将非常有帮助。提前谢谢你们。

1 个回答

2

SOCKS代理和HTTP代理是两种不同的东西。它们之间的协议不一样。下面这行代码:

b.set_proxies({"http":"96.8.113.76:8080"})

是告诉mechanize使用位于96.8.113.76:8080的HTTP代理来处理那些URL中带有http的请求,比如请求这个网址 http://httpbin.org/get,这个请求会通过96.8.113.76:8080的代理发送。mechanize期望这个代理是一个HTTP代理服务器,并使用相应的协议。但看起来你的SOCKS代理关闭了连接,因为它没有收到有效的SOCKS代理请求(实际上是一个HTTP代理请求)。

我觉得mechanize并不支持SOCKS代理,所以你可能需要用一些小技巧来解决这个问题,像这个回答中提到的那样。为此,你需要安装PySocks包。这可能对你有帮助:

import socks
import socket
from mechanize import Browser

SOCKS_PROXY_HOST = '96.8.113.76'
SOCKS_PROXY_PORT = 8080

def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

# add username and password arguments if proxy authentication required.
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT)

# patch the socket module
socket.socket = socks.socksocket
socket.create_connection = create_connection

br = Browser()
response = br.open('http://httpbin.org/get')

>>> print response.read()
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/2.7", 
    "X-Request-Id": "e728cd40-002c-4f96-a26a-78ce4d651fda"
  }, 
  "origin": "192.161.1.100", 
  "url": "http://httpbin.org/get"
}

撰写回答