If proxies is given, it must be a dictionary mapping protocol names to URLs of proxies.
但在你的代码中,它只是一个字符串。尤其是,它是proxies.txt文件中的一行:p=open('proxies.txt')
for line in p:
proxy = urllib2.ProxyHandler(line)
看一下这个文件,这些行看起来像是Python字典的repr。而且,假设所有的键和值都是字符串字面值,这意味着您可以使用ast.literal_eval来恢复原来的dict:
^{pr2}$
当然,这不适用于您的示例数据,因为其中一行缺少'字符。但如果你把它修好,它会
然而,最好使用一种实际用于数据交换的格式。例如,JSON和现有的一样容易被人理解,而且没有那么大的不同:{"https": "https://94.142.27.4:3128"}
{"http": "http://118.97.95.174:8080"}
{"http": "http://66.62.236.15:8080"}
使用JSON的好处是,有很多工具可以验证、编辑等。JSON,而对于您的自定义格式来说,没有任何工具;有效和无效的规则是显而易见的,而不是您必须猜测的;无效数据的错误消息可能更有用(例如“在第1行第10列(char10) 而不是“解析时出现意外的EOF”)。在
请注意,一旦您解决了这个问题,您将遇到另一个带有url的问题。毕竟,'www.google.com'\n不是你想要的,而是www.google.com。所以你得去掉换行符和引号。同样,您可以在这里使用ast.literal_eval。或者可以使用JSON作为交换格式。在
但实际上,如果您只是尝试每行存储一个字符串,为什么不按原样存储字符串,而不是尝试存储这些字符串的字符串表示形式(加上额外的引号)?在
除此之外,还有更多的问题。在
即使去掉了多余的引号,www.google.com也不是一个URL,它只是一个主机名。http://www.google.com就是你想要的。除非您想要https://www.google.com,或其他方案。在
您尝试为每个代理循环一次'urls.txt'。这将在只安装第一个代理的情况下处理所有的url,然后在安装前两个代理的情况下处理剩余的url(这不是什么,因为您已经完成了所有的代理),然后在安装了所有三个代理之后处理剩余的url(仍然没有)。将url循环移到proxy循环之外。在
最后,这些并不是真正的问题,但是当我们在做的时候……使用with语句比使用手动close调用更容易编写更健壮的代码,并且它使您的代码更短,更易于引导。另外,通常最好等到需要文件时再打开它。而像u和p这样的变量名从长远来看只会造成更多的混乱,而不会在短期内节省输入。在
哦,只需调用urllib.urlopen(url).read()而不对结果做任何操作除了浪费几秒钟和一点网络带宽之外不会有任何效果,但我想您已经知道了,为了简单起见,省略了细节。在
把它们放在一起,假设您按照上面所述修复了两个文件:import json
import urllib2
with open('proxies.txt') as proxies:
for line in proxies:
proxy = json.loads(line)
proxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)
with open('urls.txt') as urls:
for line in urls:
url = line.rstrip()
data = urllib.urlopen(url).read()
# do something with data
事实证明,您希望通过每个代理尝试所有URL,而不是通过所有代理尝试所有URL,或者通过第一个代理然后通过前两个代理,依此类推。在
您可以通过将第二个with和for缩进到第一个for之下来实现这一点。但是,一次读完它们可能更简单(而且可能更有效,尽管我怀疑这是否重要):with open('urls.txt') as f:
urls = [line.rstrip() for line in f]
with open('proxies.txt') as proxies:
for line in proxies:
proxy = json.loads(line)
proxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)
for url in urls:
data = urllib.urlopen(url).read()
# do something with data
当然,这意味着在做任何工作之前要阅读完整的url列表。我不确定这是否重要,但如果确实如此,您可以使用the ^{} trick来避免它。在