Python-Scrapy 个人兴趣教程(二):没错,从代理IP开始

http://blog.csdn.net/mingz_free/article/details/45967725


想要在Scrapy领域无限制畅游,做好伪装是第一步,于是乎,抓取代理IP成了很多教程的开始部分。

我十分同意这个观点,既有实际用处,又能作为一个教学,当然,对于初次使用scrapy的我,很多东西也只是在摸索阶段,所以以下内容算不上教学,只能说是练手。


完成代理IP抓取,总共分三个步骤:

  • 抓取网络上的代理IP和端口
  • 验证已经抓取的内容
  • 网络上的免费代理IP基本都有时效性,所以需要重复抓取和重复验证

这里需要用到的解决方案是:scrapy+mongo+supervisor,scrapy负责抓取,mongo是数据存储的解决方案,supervisor负责监控一个daemon,重复验证已经获得的代理IP。


scrapy教程推荐看官方的版本:scrapy官方文档,即使是翻译过的也可以,要掌握看文档的技能。

scrapy的具体使用这里不一步一步说明了,列出几个我认为叫重要的点:

  • 生成一个新的scrapy项目:
    [python]  view plain  copy
    1. scrapy startproject GoProxy  

  • scrapy.cfg是一个ini格式的配置文件,配置相关的参数可以都放在这里。
  • spiders目录下放spider的代码,执行抓取的命令跟spider类名有关。例如,我的spider叫 class ProxySpider(CrawlSpider),那么我的执行命令为:
    [python]  view plain  copy
    1. scrapy crawl Proxy  
  • items是一个收集抓取内容的容器,没有研究深入,在这个例子里作为传递给mongodb的过程变量使用。
  • pipelines是跟外部数据接口的部分,抓取的IP内容装入items后再pipelines被存入mongodb。

关于抓取规则,这是抓取类算法的核心,足够研究很久,在这里,够用足以。

代理IP抓取没有精确性的要求,10个数据漏掉5个都没关系,所以我这里使用了宽泛的正则表达式直接过滤出IP+PORT的字符串内容。代理IP网站来源于baidu和google搜索的前6页。

这种方法个人学习够用了,要想用在其他方面,这种算法抓取到的IP数量级远远不够...0 0...(一次抓取只能过滤出2000多个IP,验证后只有大概400个有效IP)


这里贴上scapy的部分源码:proxy_spider.c

[python]  view plain  copy
  1. # Spider for http proxy  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. import scrapy  
  5. from scrapy.contrib.spiders import CrawlSpider, Rule  
  6. from scrapy.contrib.linkextractors import LinkExtractor  
  7. from bs4 import BeautifulSoup  
  8. from GoProxy.items import GoproxyItem  
  9.   
  10. import re  
  11.   
  12. REG_IP = re.compile(r'((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))[^\d]*((\d){1,5})', re.M)  
  13.   
  14. class ProxySpider(CrawlSpider):  
  15.     name = "Proxy"  
  16.     #allowed_domains = ['xici.net.co', 'youdaili.net']  
  17.     start_urls = [  
  18.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy",  
  19.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=10",  
  20.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=20",  
  21.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=30",  
  22.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=40",  
  23.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=50",  
  24.             r"http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=ip%20proxy&pn=60",  
  25.             r"http://www.gfsoso.net/?q=ip+proxy&t=1",  
  26.             r"http://www.gfsoso.net/?q=ip+proxy&pn=10",  
  27.             r"http://www.gfsoso.net/?q=ip+proxy&pn=20",  
  28.             r"http://www.gfsoso.net/?q=ip+proxy&pn=30",  
  29.             r"http://www.gfsoso.net/?q=ip+proxy&pn=40",  
  30.             r"http://www.gfsoso.net/?q=ip+proxy&pn=50",  
  31.             r"http://www.gfsoso.net/?q=ip+proxy&pn=60",  
  32.     ]  
  33.   
  34.     rules = (  
  35.             Rule(LinkExtractor(allow=(r'',)), callback='parse_item'),  
  36.     )  
  37.   
  38.     def parse_item(self, response):  
  39.         soup = BeautifulSoup(response.body)  
  40.         str_list = [ tag.string or '' for tag in soup.find_all(True) ]  
  41.         body_str = ' '.join(str_list)  
  42.         items = [ GoproxyItem(ip=group[0], port=group[7], protocol='HTTP'for group in re.findall(REG_IP, body_str) ]  
  43.         return items  

pipelines.c:

[python]  view plain  copy
 
  1. # -*- coding: utf-8 -*-  
  2.   
  3. # Define your item pipelines here  
  4. #  
  5. # Don't forget to add your pipeline to the ITEM_PIPELINES setting  
  6. # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html  
  7.   
  8. import pymongo  
  9. import time  
  10. from scrapy.conf import settings  
  11.   
  12. class GoproxyPipeline(object):  
  13.     def __init__(self):  
  14.         connection = pymongo.MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])  
  15.         db = connection[settings['MONGODB_DB']]  
  16.         self.collection = db[settings['MONGODB_COLLECTION']]  
  17.   
  18.     def process_item(self, item, spider):  
  19.         new_proxy = {  
  20.             "ip":item['ip'],  
  21.             "port":item['port'],  
  22.             "protocol":item['protocol'],  
  23.         }  
  24.         if self.collection.find_one(new_proxy) is None:  
  25.             self.collection.insert(new_proxy)  
  26.   
  27.         return item  


在调试完成后,用crontab把这个抓取定制为每半小时执行一次,= =保证数据库里的都是新鲜的IP~~~~。

[plain]  view plain  copy
 
  1. 0,30 * * * *  cd /root/work/repos/GoProxy/&&/usr/local/bin/scrapy crawl Proxy  


这样,抓取代理IP的初步工作就完成了,下一篇会简单介绍一下代理IP的验证,我使用的是daemon的形式,只要mongodb的对应collection里面有数据,就将数据去除验证,如果验证成功,则放入另一个collection,对于这个存放有效数据的collection也同样有:取出->验证->放回,的过程。至于为什么不用一个collection搞定,纯属喜好问题:)

你可能感兴趣的:(Python-Scrapy 个人兴趣教程(二):没错,从代理IP开始)