这里有新鲜出炉的 Python 入门,程序狗速度看过来!
Python 是一种面向对象、解释型计算机程序设计语言,由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。Python 语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是 C/C++)很轻松地联结在一起。
下面小编就为大家带来一篇 python 扫描 proxy 并获取可用代理 ip 的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
今天咱写一个挺实用的工具,就是扫描并获取可用的 proxy
首先呢,我先百度找了一个网站:http://www.xicidaili.com 作为例子
这个网站里公布了许多的国内外可用的代理的 ip 和端口
我们还是按照老样子进行分析,就先把所有国内的 proxy 扫一遍吧
点开国内部分进行审查发现,国内 proxy 和目录为以下 url:
http://www.xicidaili.com/nn/x
这个 x 差不多两千多页,那么看来又要线程处理了。。。
老样子,我们尝试是否能直接以最简单的 requests.get() 获取内容
返回 503,那么我们加一个简单的 headers
返回 200,成咯
好了我们先进行网页内容分析并获取想要的内容
我们发现,包含 ip 信息的内容在 <tr> 标签内,于是我们就能很方便的用 bs 进行获取标签内容
但是我们随之又发现,ip、端口、协议的内容分别在提取的 <tr> 标签的第 2,3,6 三个 <td> 标签内
于是我们开始尝试编写,一下为编写思路:
处理页面的时候,是先提取 tr 标签,再将 tr 标签中的 td 标签提取
所以运用了两次 bs 操作,并且第二次使用 bs 操作时需要进行 str 处理
因为我们获得 tr 之后,我们需要其中的 2,3,6 号的东西,
但是当我们用一个 for 循环输出的 i 并不能进行组的操作
所以我们干脆分别对每一个 td 的 soup 进行第二次操作之后直接提取 2,3,6
提取之后,直接加上. string 提取内容即可
- r = requests.get(url = url,headers = headers)
- soup = bs(r.content,"html.parser")
- data = soup.find_all(name = 'tr',attrs = {'class':re.compile('|[^odd]')})
- for i in data:
- soup = bs(str(i),'html.parser')
- data2 = soup.find_all(name = 'td')
- ip = str(data2[1].string)
- port = str(data2[2].string)
- types = str(data2[5].string).lower()
- proxy = {}
- proxy[types] = '%s:%s'%(ip,port)
这样,我们每次循环都能生成对应的 proxy 字典,以便我们接下来验证 ip 可用性所使用
字典这儿有个注意点,我们有一个将 types 变为小写的操作,因为在 get 方法中的 proxies 中写入的协议名称应为小写,而网页抓取的是大写的内容,所以进行了一个大小写转换
那么验证 ip 可用性的思路呢
很简单,我们使用 get,加上我们的代理,请求网站:
http://1212.ip138.com/ic.asp
这是一个神奇的网站,能返回你的外网 ip 是什么
- url = 'http://1212.ip138.com/ic.asp'
- r = requests.get(url = url,proxies = proxy,timeout = 6)
这里我们需要加上 timeout 去除掉那些等待时间过长的代理,我设置为 6 秒
我们以一个 ip 进行尝试,并且分析返回的页面
返回的内容如下:
- <html>
- <head>
- <meta xxxxxxxxxxxxxxxxxx>
- <title> 您的IP地址 </title>
- </head>
- <body style="margin:0px"><center>您的IP是:[xxx.xxx.xxx.xxx] 来自:xxxxxxxx</center></body></html>
那么我们只需要提取出网页内 [] 的内容即可
如果我们的代理可用,就会返回代理的 ip
(这里会出现返回的地址还是我们本机的外网 ip 的情况,虽然我也不是很清楚,但是我把这种情况排除,应该还是代理不可用)
那么我们就能进行一个判断,如果返回的 ip 和 proxy 字典中的 ip 相同,则认为这个 ip 是可用的代理,并将其写入文件
我们的思路就是这样,最后进行 queue 和 threading 线程的处理即可
上代码:
- #coding=utf-8
- import requests
- import re
- from bs4 import BeautifulSoup as bs
- import Queue
- import threading
- class proxyPick(threading.Thread):
- def __init__(self,queue):
- threading.Thread.__init__(self)
- self._queue = queue
- def run(self):
- while not self._queue.empty():
- url = self._queue.get()
- proxy_spider(url)
- def proxy_spider(url):
- headers = {
- .......
- }
- r = requests.get(url = url,headers = headers)
- soup = bs(r.content,"html.parser")
- data = soup.find_all(name = 'tr',attrs = {'class':re.compile('|[^odd]')})
- for i in data:
- soup = bs(str(i),'html.parser')
- data2 = soup.find_all(name = 'td')
- ip = str(data2[1].string)
- port = str(data2[2].string)
- types = str(data2[5].string).lower()
- proxy = {}
- proxy[types] = '%s:%s'%(ip,port)
- try:
- proxy_check(proxy,ip)
- except Exception,e:
- print e
- pass
- def proxy_check(proxy,ip):
- url = 'http://1212.ip138.com/ic.asp'
- r = requests.get(url = url,proxies = proxy,timeout = 6)
- f = open('E:/url/ip_proxy.txt','a+')
- soup = bs(r.text,'html.parser')
- data = soup.find_all(name = 'center')
- for i in data:
- a = re.findall(r'\[(.*?)\]',i.string)
- if a[0] == ip:
- #print proxy
- f.write('%s'%proxy+'\n')
- print 'write down'
- f.close()
- #proxy_spider()
- def main():
- queue = Queue.Queue()
- for i in range(1,2288):
- queue.put('http://www.xicidaili.com/nn/'+str(i))
- threads = []
- thread_count = 10
- for i in range(thread_count):
- spider = proxyPick(queue)
- threads.append(spider)
- for i in threads:
- i.start()
- for i in threads:
- i.join()
- print "It's down,sir!"
- if __name__ == '__main__':
- main()
这样我们就能把网站上所提供的能用的代理 ip 全部写入文件 ip_proxy.txt 文件中了
以上这篇 python 扫描 proxy 并获取可用代理 ip 的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持 PHPERZ。
来源: http://www.phperz.com/article/17/0822/344564.html