Scrapy突破反爬虫的限制
随机切换UserAgent
https://github.com/hellysmile/fake-useragent
scrapy使用fake-useragent
在全局配置文件中禁用掉默认的UA,将其设置为None即可
settings.py
DOWNLOADER_MIDDLEWARES = {
...
'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
}
在中间件中编写自己的middleware
middlewares.py
class RandomUserAgentMiddleware(object):
def __init__(self, crawler):
super(RandomUserAgentMiddleware, self).__init__()
self.ua = UserAgent()
self.ua_type = crawler.settings.get('RANDOM_UA_TYPE', 'random')
@classmethod
def from_crawler(cls, crawler):
return cls(crawler)
def process_request(self, request, spider):
def get_ua():
return getattr(self.ua, self.ua_type)
request.headers.setdefault('User-Agent', get_ua())
将自己写的middleware配置进settings中
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.CustomDownloaderMiddleware': 543,
'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
}
随机切换IP
https://github.com/scrapy-plugins/scrapy-crawlera
爬取西刺IP代理网站获取IP
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from w3lib.html import remove_tags
from ArticleSpider.items import ProxyIpItemLoader, ProxyIpItem
class ProxyIpSpider(CrawlSpider):
name = 'proxy'
allowed_domains = ['www.xicidaili.com']
start_urls = ['http://www.xicidaili.com']
rules = (
Rule(LinkExtractor(allow=('nn/\d*')), callback='parse_detail', follow=True),
)
def parse_detail(self, response):
ip_list = response.css('#ip_list tr')
for ipdata in ip_list[1:]:
item_loader = ProxyIpItemLoader(item=ProxyIpItem(), response=response)
data = ipdata.css('td')
item_loader.add_value('ip', data[1].css('td::text').extract_first())
item_loader.add_value('port', data[2].css('td::text').extract_first())
item_loader.add_value('addr', self.get_addr(data[3]))
item_loader.add_value('ishidden', data[4].css('td::text').extract_first())
item_loader.add_value('type', data[5].css('td::text').extract_first())
item_loader.add_value('speed', data[6].css('div::attr(title)').extract_first())
item_loader.add_value('conn_time', data[7].css('div::attr(title)').extract_first())
item_loader.add_value('live_time', data[8].css('td::text').extract_first())
item_loader.add_value('check_time', data[9].css('td::text').extract_first())
proxy_ip_item = item_loader.load_item()
yield proxy_ip_item
def get_addr(self, value):
if value.css('a'):
return remove_tags(value.extract()).strip()
else:
return "未知"
对数据进行简单处理
class ProxyIpItemLoader(ItemLoader):
default_output_processor = TakeFirst()
def live_time(value):
'''
分钟, 小时, 天
统一转换成分钟
'''
if '分钟' in value:
return int(value.split('分钟')[0])
elif '小时' in value:
value = value.split('小时')[0]
return int(value) * 60
elif '天' in value:
value = value.split('天')[0]
return int(value) * 60 * 24
def ishidden_to_int(value):
if '高匿' in value:
return int(1)
else:
return int(0)
def check_time(value):
return datetime.datetime.strptime(value, "%y-%m-%d %H:%M")
class ProxyIpItem(scrapy.Item):
'''
{'addr': '陕西西安',
'check_time': '12-12-31 18:52',
'conn_time': '0.82秒',
'ip': '113.133.160.203',
'ishidden': '高匿',
'live_time': '1分钟',
'port': '6675',
'speed': '3.595秒',
'type': 'socks4/5'
}
'''
ip = scrapy.Field()
port = scrapy.Field()
addr = scrapy.Field(
input_processor = MapCompose(remove_tags, lambda x:x.strip())
)
ishidden = scrapy.Field(
input_processor=MapCompose(ishidden_to_int)
)
type = scrapy.Field()
speed = scrapy.Field()
conn_time = scrapy.Field()
live_time = scrapy.Field(
input_processor = MapCompose(live_time)
)
check_time = scrapy.Field()
def get_insert_sql(self):
insert_sql = """
insert into proxy_ip(ip, port, addr, ishidden, type, speed, conn_time, live_time, check_time)
VALUES (%s, %s, %s, %s,%s,%s, %s, %s, %s)
"""
params = (self["ip"], self["port"], self["addr"],
self["ishidden"], self["type"],self["speed"],
self["conn_time"], self["live_time"], self["check_time"])
return insert_sql, params
在pipeline中进行数据的再次清洗,抛弃所有的特殊端口的item,并数据进行保存
在中间件中创建切换IP的中间件,在主配置文件中启用这个中间件
IP是否可用,只需要请求百度即可
验证码识别
没必要自己写一个验证码识别代码
可以使用云打码平台进行验证码识别
http://www.yundama.com/
需要分别注册一个普通用户和一个开发者账号
下载pythonhttp版本
http://www.yundama.com/apidoc/YDM_SDK.html#DLL
解压后里面有一个3.x的文件,打开后进行配置
# 用户名(普通用户)
username = 'username'
# 密码(普通用户)
password = 'password'
# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid = 1
# 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '22cc5376925e9387a23cf797cb9ba745'
# 图片文件
filename = 'getimage.jpg'
# 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
codetype = 1004
# 超时时间,秒
timeout = 60
Scrapy突破反爬虫的限制的更多相关文章
- Python Scrapy突破反爬虫机制(项目实践)
对于 BOSS 直聘这种网站,当程序请求网页后,服务器响应内容包含了整个页面的 HTML 源代码,这样就可以使用爬虫来爬取数据.但有些网站做了一些“反爬虫”处理,其网页内容不是静态的,而是使用 Jav ...
- 第7章 Scrapy突破反爬虫的限制
7-1 爬虫和反爬的对抗过程以及策略 Ⅰ.爬虫和反爬虫基本概念 爬虫:自动获取网站数据的程序,关键是批量的获取. 反爬虫:使用技术手段防止爬虫程序的方法. 误伤:反爬虫技术将普通用户识别为爬虫,如果误 ...
- Scrapy爬取美女图片第四集 突破反爬虫(上)
本周又和大家见面了,首先说一下我最近正在做和将要做的一些事情.(我的新书<Python爬虫开发与项目实战>出版了,大家可以看一下样章) 技术方面的事情:本次端午假期没有休息,正在使用fl ...
- 自动更改IP地址反爬虫封锁,支持多线程(转)
8年多爬虫经验的人告诉你,国内ADSL是王道,多申请些线路,分布在多个不同的电信机房,能跨省跨市更好,我这里写好的断线重拨组件,你可以直接使用. ADSL拨号上网使用动态IP地址,每一次拨号得到的IP ...
- Python Scrapy反爬虫常见解决方案(包含5种方法)
爬虫的本质就是“抓取”第二方网站中有价值的数据,因此,每个网站都会或多或少地采用一些反爬虫技术来防范爬虫.比如前面介绍的通过 User-Agent 请求头验证是否为浏览器.使用 JavaScript ...
- 第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图
第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图 1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scra ...
- 二十四 Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图
1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scrapy架构源码分析图
- scrapy反反爬虫
反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...
- scrapy反反爬虫策略和settings配置解析
反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...
随机推荐
- 解决Android Studio 错误方法
https://blog.csdn.net/lang523493505/article/details/82914253 https://blog.csdn.net/qq_23599965/artic ...
- DSSM:深度语义匹配模型(及其变体CLSM、LSTM-DSSM)
导语 在NLP领域,语义相似度的计算一直是个难题:搜索场景下Query和Doc的语义相似度.feeds场景下Doc和Doc的语义相似度.机器翻译场景下A句子和B句子的语义相似度等等.本文通过介绍DSS ...
- Java Arrays工具类的使用
Arrays 类 java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的.具有以下功能: 给数组赋值:通过fill方法. 对数组排序:通过sort方法,按升序. 比较数组:通过 ...
- Jmeter(三十七)循环控制器+交替控制器+事务控制器 完美实现接口字段参数化校验
我们在做接口自动化的时候,常常因为无法灵活的的校验接口字段而烦恼.不能自动校验接口字段的脚本,也就不能称之为接口自动化.因此,我设计了一套组合式的控制器,可以完美的解决这个问题 1:首先我们需要在本地 ...
- java----牛客练习
1. 形式参数就是函数定义时设定的参数.例如函数头 int min(int x,int y,int z) 中 x,y,z 就是形参.实际参数是调用函数时所使用的实际的参数. 真正被传递的是实参 ...
- .net之httphandler小记
本地调试代码遇到的一个问题,没有走URL路由器(UrlReWriter : IHttpHandlerFactory),于是网上科普了一下原理,主要有两点: 1.asp.net在处理http请求时,会由 ...
- 线程中的samaphore信号量及event事件
一.信号量 samaphore: 在程序中意思为同时允许几个线程运行,比如我们去水上乐园的滑梯玩时,有四个滑梯,每一个滑梯上当没有人在中间玩滑下去时才允许上人,四个滑梯1,2,3,4,同时最多四个人, ...
- 【学习总结】 小白CS成长之路
2017-9-3:入坑. 理想:敲着代码唱着歌. 现实:骨感. Step 1: 认识CS: CS大体可以分成以下几个大领域:硬件.系统.软件.网络.计算理论.计算方法. 硬 件 ---- 数字电路.集 ...
- 简述nginx(1)
Nginx能做什么 1.反向代理 2.负载均衡 3.HTTP服务器(包含动静分离) 4.正向代理 反向代理 反向代理应该是Nginx做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理 ...
- html5-attr和prop
###1.什么是attrbute和property attribute(attr) html标签的预定义属性 checked html标签的自定义属性 a eg: <input ...