目录
Downloader Middlewares单个ip代理
ip代理要写在Downloader Middlewares下载器里,对request进行修改就行,关键代码就一行:request.meta['proxy'] = 代理IP
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from scrapy import signals class RandomUserAgentDownloaderMiddleware(object): def __init__(self, crawler): super(RandomUserAgentDownloaderMiddleware, self).__init__() @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_request(self, request, spider): # ip代理 request.meta['proxy'] = 'https://58.62.238.150:32431' |
IP代理池
爬取IP代理网站,生成IP代理池
西刺免费代理IP(www.xicidaili.com)有免费的代理IP,我们可以爬取上面的IP信息,存到本地作为IP代理池。
我们需要爬取的数据有:IP地址、端口、类型三个。
高匿:不会暴露你的真实IP地址。
非高匿:有可能会暴露你的真实IP地址。
所以,最好选择高匿。
编写爬虫代码
在项目下,新建一个名为tools的文件夹,在tools文件夹里新建crawl_xici_ip.py的文件,用来编写爬取ip代理的爬虫文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
#!/usr/bin/env python # -*- coding: utf-8 -*- import requests # 引入下载器 from scrapy.selector import Selector # 引入scrapy的选择器 import MySQLdb # 引入数据库类库 # 数据库的链接信息 conn = MySQLdb.connect( host = '127.0.0.1', db = 'benzadmin', user = 'root', password = 'root', charset = 'utf8', ) # 实例化数据库的游标 cursor = conn.cursor() # 爬取西刺网的代理IP def crawl_ips(): # 定义头信息 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} # 全部有3461页,循环请求 for i in range(3461): # 请求网页 re = requests.get('http://www.xicidaili.com/nn/{0}'.format(i),headers=headers) # 实例化选择器 selector = Selector(text=re.text) all_trs = selector.css('#ip_list tr') # 获取有用的信息 ip_list = [] for tr in all_trs[1:]: speed_str = tr.css('.bar::attr(title)').extract_first('') if speed_str: speed = float(speed_str.split('秒')[0]) all_texts = tr.css('td::text').extract() ip = all_texts[0] # ip port = all_texts[1] # 端口 proxy_type = all_texts[5] # 代理类型 # 进站 ip_list.append((ip,port,proxy_type,speed)) # 编写入库的SQL语句 for ip_info in ip_list: cursor.execute( "insert into ips(ip,port,speed,proxy_type) values ('{0}','{1}','{2}','http')".format( ip_info[0],ip_info[1],ip_info[3] )) # 提交指令 conn.commit() # 从数据库中随机取出ip class GetIP(object): # 从数据库中,删除无效的ip def delete_ip(self,ip): delete_sql = """ delete from ips where ip='{0}' """.format(ip) cursor.execute(delete_sql) conn.commit() return True # 判断ip是否有效 def judge_ip(self,ip,port): http_url = 'https://www.baidu.com' proxy_url = 'https://{0}:{1}'.format(ip,port) proxy_dict = { 'https':proxy_url } try: respons = requests.get(http_url,proxies=proxy_dict) except Exception as e: print('无效的IP与端口') self.delete_ip(ip) return False else: code = respons.status_code if code >=200 and code <300: print('有效的IP') return True else: print('无效的ip') self.delete_ip(ip) return False # 从数据库中获取随机ip def get_random_ip(self): random_sql = """ SELECT ip,port from ips ORDER BY RAND() LIMIT 1 """ cursor.execute(random_sql) # cursor.fetchall()查询所有得到的数据 for ip_info in cursor.fetchall(): ip = ip_info[0] port = ip_info[1] judge_re = self.judge_ip(ip,port) # 判断有效就返回IP if judge_re: return 'https://{0}:{1}'.format(ip,port) else: # 判断无效就重新获取IP return self.get_random_ip() #crawl_ips() if __name__ == '__main__': get_ip = GetIP() get_ip.get_random_ip() |
在middlewares.py中编写拦截器
1 2 3 4 5 6 7 8 9 |
from tools.crawl_xici_ip import GetIP # 随机代理ip的middlewares class RandomProxyIPDownloaderMiddleware(object): # 动态设置IP代理 def process_request(self, request, spider): get_ip = GetIP() # ip代理 request.meta['proxy'] = get_ip.get_random_ip() |
最后在settings.py注册middlewares:
1 2 3 |
DOWNLOADER_MIDDLEWARES = { 'ArticleSpider.middlewares.RandomProxyIPDownloaderMiddleware': 1, } |
ip代理的开源库与工具
scrapy-proxies
项目地址:https://github.com/aivarsk/scrapy-proxies
scrapy-crawlera
项目地址:https://github.com/scrapy-plugins/scrapy-crawlera,功能强大,配置简单,但是,要收费。
Tor洋葱浏览器
会把我们的请求进行多次的转发,以达到隐藏真实IP的目的,比收费的项目还要稳定一些。