尝试使用Python多线程抓取代理服务器IP地址的示例


Posted in Python onNovember 09, 2015

这里以抓取 http://www.proxy.com.ru 站点的代理服务器为例,代码如下:

#!/usr/bin/env python
#coding:utf-8
import urllib2
import re
import threading
import time
import MySQLdb
rawProxyList = []
checkedProxyList = []
#抓取代理网站
targets = []
for i in xrange(1,42):
  target = r"http://www.proxy.com.ru/list_%d.html" % i
  targets.append(target)
#抓取代理服务器正则
p = re.compile(r'''<tr><b><td>(\d+)</td><td>(.+?)</td><td>(\d+)</td><td>(.+?)</td><td>(.+?)</td></b></tr>''')
#获取代理的类
class ProxyGet(threading.Thread):
 def __init__(self,target):
  threading.Thread.__init__(self)
  self.target = target
 def getProxy(self):
  print "代理服务器目标网站: " + self.target
  req = urllib2.urlopen(self.target)
  result = req.read()
  #print chardet.detect(result)
  matchs = p.findall(result)
#  print matchs
  for row in matchs:
   ip=row[1]
   port =row[2]
   addr = row[4].decode("cp936").encode("utf-8")
   proxy = [ip,port,addr]
   print proxy
   rawProxyList.append(proxy)
 def run(self):
  self.getProxy()
#检验代理的类
class ProxyCheck(threading.Thread):
 def __init__(self,proxyList):
  threading.Thread.__init__(self)
  self.proxyList = proxyList
  self.timeout = 5
  self.testUrl = "http://www.baidu.com/"
  self.testStr = "030173"
 def checkProxy(self):
  cookies = urllib2.HTTPCookieProcessor()
  for proxy in self.proxyList:
   proxyHandler = urllib2.ProxyHandler({"http" : r'http://%s:%s' %(proxy[0],proxy[1])})
   #print r'http://%s:%s' %(proxy[0],proxy[1])
   opener = urllib2.build_opener(cookies,proxyHandler)
   opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0')]
   #urllib2.install_opener(opener)
   t1 = time.time()
   try:
    #req = urllib2.urlopen("http://www.baidu.com", timeout=self.timeout)
    req = opener.open(self.testUrl, timeout=self.timeout)
    #print "urlopen is ok...."
    result = req.read()
    #print "read html...."
    timeused = time.time() - t1
    pos = result.find(self.testStr)
    #print "pos is %s" %pos
    if pos > 1:
     checkedProxyList.append((proxy[0],proxy[1],proxy[2],timeused))
     #print "ok ip: %s %s %s %s" %(proxy[0],proxy[1],proxy[2],timeused)
    else:
      continue
   except Exception,e:
    #print e.message
    continue
 def run(self):
  self.checkProxy()
if __name__ == "__main__":
 getThreads = []
 checkThreads = []
#对每个目标网站开启一个线程负责抓取代理
for i in range(len(targets)):
 t = ProxyGet(targets[i])
 getThreads.append(t)
for i in range(len(getThreads)):
 getThreads[i].start()
for i in range(len(getThreads)):
 getThreads[i].join()
print '.'*10+"总共抓取了%s个代理" %len(rawProxyList) +'.'*10
#开启20个线程负责校验,将抓取到的代理分成20份,每个线程校验一份
for i in range(20):
 t = ProxyCheck(rawProxyList[((len(rawProxyList)+19)/20) * i:((len(rawProxyList)+19)/20) * (i+1)])
 checkThreads.append(t)
for i in range(len(checkThreads)):
 checkThreads[i].start()
for i in range(len(checkThreads)):
 checkThreads[i].join()
print '.'*10+"总共有%s个代理通过校验" %len(checkedProxyList) +'.'*10
#插入数据库,表结构自己创建,四个字段ip,port,speed,address
def db_insert(insert_list):
 try:
  conn = MySQLdb.connect(host="localhost", user="root", passwd="admin",db="m_common",charset='utf8')
  cursor = conn.cursor()
  cursor.execute('delete from proxy')
  cursor.execute('alter table proxy AUTO_INCREMENT=1')
  cursor.executemany("INSERT INTO proxy(ip,port,speed,address) VALUES (%s,%s,%s,%s)",insert_list)
  conn.commit()
  cursor.close()
  conn.close()
 except MySQLdb.Error,e:
  print "Mysql Error %d: %s" % (e.args[0], e.args[1])
#代理排序持久化
proxy_ok = []
f= open("proxy_list.txt",'w+')
for proxy in sorted(checkedProxyList,cmp=lambda x,y:cmp(x[3],y[3])):
 if proxy[3] < 8:
  #print "checked proxy is: %s:%s\t%s\t%s" %(proxy[0],proxy[1],proxy[2],proxy[3])
  proxy_ok.append((proxy[0],proxy[1],proxy[3],proxy[2]))
  f.write("%s:%s\t%s\t%s\n"%(proxy[0],proxy[1],proxy[2],proxy[3]))
f.close()
db_insert(proxy_ok)

测试:

python proxy.py

结果如下:

['61.58.94.179', '8088', '\xe5\x8f\xb0\xe6\xb9\xbe\xe7\x9c\x81 \xe5\x8f\xb0\xe6\xb9\xbe\xe5\xae\xbd\xe9\xa2\x91\xe9\x80\x9a\xe8\xae\xaf\xe9\xa1\xbe\xe9\x97\xae\xe8\x82\xa1\xe4\xbb\xbd\xe6\x9c\x89\xe9\x99\x90\xe5\x85\xac\xe5\x8f\xb8']
['200.84.116.99', '9064', '\xe5\xa7\x94\xe5\x86\x85\xe7\x91\x9e\xe6\x8b\x89 ']
['183.223.204.8', '8123', '\xe5\x9b\x9b\xe5\xb7\x9d\xe7\x9c\x81\xe8\x87\xaa\xe8\xb4\xa1\xe5\xb8\x82 \xe7\xa7\xbb\xe5\x8a\xa8']
..........总共抓取了1921个代理..........
..........总共有524个代理通过校验..........
# more proxy_list.txt
202.106.169.142:80  北京市 联通ADSL 0.291432857513
111.13.136.59:80  北京市 移动  0.297957897186
111.13.136.56:80  北京市 移动  0.373070955276
111.206.81.248:80  北京市 联通  0.403017997742
111.13.136.58:80  北京市 移动  0.414332151413
124.202.217.134:8118 北京市 电信通 0.416817903519
124.202.183.218:8118 北京市 电信通 0.426618099213
120.132.71.232:80  北京市 联通  0.440200090408
61.232.6.164:8081  北京市 铁通  0.469615936279
118.144.96.253:80  北京市 电信通 0.485229969025
203.192.10.66:80  北京市 新华社 0.51485991478
124.202.182.22:8118  北京市 电信通 0.553130865097

数据库:

mysql> select * from m_common.proxy limit 10;
+----------+-----------------+------+----------+----------------------+---------------------+
| proxy_id | ip    | port | speed | address    | create_time   |
+----------+-----------------+------+----------+----------------------+---------------------+
|  1 | 202.106.169.142 | 80 | 0.291433 | 北京市 联通ADSL  | 2015-02-26 11:29:24 |
|  2 | 111.13.136.59 | 80 | 0.297958 | 北京市 移动   | 2015-02-26 11:29:24 |
|  3 | 111.13.136.56 | 80 | 0.373071 | 北京市 移动   | 2015-02-26 11:29:24 |
|  4 | 111.206.81.248 | 80 | 0.403018 | 北京市 联通   | 2015-02-26 11:29:24 |
|  5 | 111.13.136.58 | 80 | 0.414332 | 北京市 移动   | 2015-02-26 11:29:24 |
|  6 | 124.202.217.134 | 8118 | 0.416818 | 北京市 电信通  | 2015-02-26 11:29:24 |
|  7 | 124.202.183.218 | 8118 | 0.426618 | 北京市 电信通  | 2015-02-26 11:29:24 |
|  8 | 120.132.71.232 | 80 | 0.4402 | 北京市 联通   | 2015-02-26 11:29:24 |
|  9 | 61.232.6.164 | 8081 | 0.469616 | 北京市 铁通   | 2015-02-26 11:29:24 |
|  10 | 118.144.96.253 | 80 | 0.48523 | 北京市 电信通  | 2015-02-26 11:29:24 |
+----------+-----------------+------+----------+----------------------+---------------------+
10 rows in set (0.00 sec)
Python 相关文章推荐
Python多线程编程(二):启动线程的两种方法
Apr 05 Python
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
Mar 19 Python
简述Python2与Python3的不同点
Jan 21 Python
python实现简单五子棋游戏
Jun 18 Python
python对绑定事件的鼠标、按键的判断实例
Jul 17 Python
Django Docker容器化部署之Django-Docker本地部署
Oct 09 Python
关于ZeroMQ 三种模式python3实现方式
Dec 23 Python
pycharm设置当前工作目录的操作(working directory)
Feb 14 Python
什么是python的id函数
Jun 11 Python
使用python matploblib库绘制准确率,损失率折线图
Jun 16 Python
python 经纬度求两点距离、三点面积操作
Jun 03 Python
python小型的音频操作库mp3Play
Apr 24 Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 #Python
Python中MySQLdb和torndb模块对MySQL的断连问题处理
Nov 09 #Python
使用Python对IP进行转换的一些操作技巧小结
Nov 09 #Python
Python实现模拟时钟代码推荐
Nov 08 #Python
用Python的Flask框架结合MySQL写一个内存监控程序
Nov 07 #Python
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
Nov 07 #Python
举例讲解Linux系统下Python调用系统Shell的方法
Nov 07 #Python
You might like
PHP 截取字符串专题集合
2010/08/19 PHP
jQuery代码优化 遍历篇
2011/11/01 Javascript
js数值和和字符串进行转换时可以对不同进制进行操作
2014/03/05 Javascript
javascript简单实现命名空间效果
2014/03/06 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
2014/04/25 Javascript
JavaScript中对象property的读取和写入方法介绍
2014/12/30 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
Bootstrap每天必学之导航条(二)
2016/03/01 Javascript
JavaScript鼠标特效大全
2016/09/13 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
jQuery实现两个select控件的互移操作
2016/12/22 Javascript
在vue中获取dom元素内容的方法
2017/07/10 Javascript
微信小程序单选radio及多选checkbox按钮用法示例
2019/04/30 Javascript
微信小程序时间戳转日期的详解
2019/04/30 Javascript
详解如何提升JSON.stringify()的性能
2019/06/12 Javascript
vue-cli随机生成port源码的方法
2019/09/02 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
Python使用正则匹配实现抓图代码分享
2015/04/02 Python
Python写的一个简单监控系统
2015/06/19 Python
Python heapq使用详解及实例代码
2017/01/25 Python
Python操作csv文件实例详解
2017/07/31 Python
Django 中使用流响应处理视频的方法
2018/07/20 Python
Python装饰器基础概念与用法详解
2018/12/22 Python
详解Python的三种拷贝方式
2020/02/11 Python
详解三种方式实现平滑滚动页面到顶部的功能
2019/04/23 HTML / CSS
HTML5播放实现rtmp流直播
2020/06/16 HTML / CSS
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
探索欧洲最好的品牌:Bombinate
2019/06/14 全球购物
给护士表扬信
2014/01/19 职场文书
公司采购主管岗位职责
2014/06/17 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书
土地租赁协议书
2015/01/29 职场文书
2016年六一文艺汇演开幕词
2016/03/04 职场文书
详解python字符串驻留技术
2021/05/21 Python
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技