最近在从事数据聚合技术研发工作,刚开始我主要是聚合工商的企业数据源、专利网的数据源、裁判文书网的数据源,刚开始遇到不少的坑,各种验证码、各种封IP等限制。做数据聚合研发首先的技术是Python,因为Python具有很多强大的现存的库可以直接用的,比如: 图像识别库、requests库等,下面就关于 模拟请求爬取天某查的整套架构设计+核心代码分享给大家,主要是解决大家在写python爬虫过程中遇到验证码问题、封IP问题、分页爬不完问题、还有爬取的效率和速度问题。
做大数据,首先应该评估一下数据量有多大,比如当时我爬的天某查应该是千万级上亿级的数据,我们需要做一个大数据架构来支撑这个亿级的数量存储和爬取工作,免得到时数据大了都动不了,反而就是这个灾难,下面是整体架构图:
原始库:数据库我们实现读写分离的简易架构,python爬虫不断的把数据采集下来并且写入到原始数据库,写入的时候不用做去重的判断,因为如果您在写入的时候就判断是否存在再去入库,那么当一个表里面有几千万的数据你逐个去匹配去重时候 速度是非常慢的,几十分钟你才能成功插入一条新的数据,所以这个时候我们就应该把判断去重的工作交付给异步清洗处理,尽可能让采集新数据的工作压力越小越好,这样采集的速度就很快,爬虫就负责一直采集入库即可。
标准库:我们中间会有一个数据清洗过程,数据清洗其实很简单,就是把原始库的数据异步复制到标准库中,只是在复制插入到标准库的过程中先判断标准库是否已经存在该条数据了,如果存在就更新之前没有的字段,如果不存在就直接插入库一条。
数据清洗:我们一程序实现数据库复制和判断去重的,把原始库的数据复制一份到标准库后,立刻把原始库的意见清洗过的数据删除掉,为什么需要删除掉原始库已经清洗过的数据呢?因为如果不擅长,那么原始库越来越大,以后每次清洗数据量越来越大而且都是重复清洗,导致清洗工作重复和压力大。
代理IP池:也许您会问这个代理IP池是做什么,又是怎么实现的呢?我们在爬网站的时候,需要用代理ip不能用我们自己电脑的IP去爬,原因是在你电脑直接运行代码那么爬虫的IP就是你电脑的IP ,如果一直频繁的去采集对方的网站,那么对方会检测到您的IP直接把您的IP列入黑名单导致你以后在也采集不了了。所以我所有的批量采集爬虫都采用代理IP去爬的,python怎么采用代理IP呢?其实很简单就那么一行代码就解决:
resp = requests.get(url, headers=self.headers, timeout=20, proxies=proxy)
我们调用的是 requests的get方法 里面有url、和headers以及 , proxies代理IP设置的参数。
url:就是我们采集的目标网站地址
headers:就是我们模拟访问对方网站时候需要模拟的头参数(这个参数怎么来呢,其实很简单,直接用火狐打开对方网站 查看网络里面有和请求头 那些参数复制过来即可)
Proxies:就是我们的设置我们的代理IP,代理IP是什么意思呢?代理服务器的工作机制很象我们生活中常常提及的代理商,假设你的机器为A机,你想获得的数据由B机提供,代理服务器为C机,那么具体的连接过程是这样的。 首先,A它与C机建立连接把请求发给C,C机接收到A机的数据请求后马上与B机建立连接,下载A机所请求的B机上的数据到本地,再将此数据发送至A机,完成代理任务。这样下载对方网站的数据的是代理服务器,而这个代理服务器IP是随机变动,对方就抓不到是谁一直采集他的数据了。那这个代理ip我们清楚了,这个ip代理池又是什么呢?我们运行我们的python程序的时候,每秒发一个http请求去爬对方网站一次,请求一次需要一个IP,那么这个ip怎么来呢?我们可以网上购买第三方那种ip接口,比如:每10秒中会返回1个IP给我们用,如果我们每次爬数据都先要调取代理IP接口得到IP了再去爬对方网站 那么这个效率和代码质量就低了,因为人家是10秒中才一个IP,您的程序速度和效率就直接卡在因为代理IP接口控制问题了,所以这个时候您需要改进代理IP代码架构,首先每10秒中读取代理IP接口得到的IP 缓存到reis去,并且设置60秒过期,那么这个redis就会形成一个代理IP池了,您的程序代码爬对方网站时候直接从redis读取IP去爬,这样速度就快了,程序架构就优化了。
模拟请求某某查-代码部分:
def get_html(url, mheaders={}, cookies={}):
while True:
try:
proxy = get_proxy() # 获取代理-自定义一个方法从redis读取代理Ip
if not mheaders:
resp = requests.get(url, headers=headers, cookies=cookies, proxies=proxy, timeout=3)
else:
resp = requests.get(url, headers=mheaders, cookies=cookies, proxies=proxy, timeout=3)
if 'tianyancha' in url:
if resp.status_code == requests.codes.ok:
if '请输入验证码' not in resp.text:
return resp.text
else:
print('{}被封了!'.format(proxy))
elif '融资历史' in resp.text:
return resp.text
else:
print('错误的代码编号:{}, url:{}'.format(resp.status_code, url))
else:
if resp.status_code == requests.codes.ok:
if '小查为' in resp.text or '基本信息' in resp.text:
return resp.text
else:
print('错误的代码编号:{}, url:{}'.format(resp.status_code, url))
except Exception as e:
print('url :{},错误:{}'.format(url, e))
#读取redis缓存的代理IP的方法
import requests
import redis
from config import REDIS_HOST, REDIS_PORT, REDIS_DB
def get_proxy():
redis_r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)#从redis读取缓存代理池IP
keys = redis_r.keys("proxy_*") #redis_r.keys()
if(keys):
for key in keys:
if key.decode().startswith('proxy_'):
proxy = {'https': 'https://{}'.format(redis_r.get(key).decode()),'http': 'http://{}'.format(redis_r.get(key).decode())}
#redis_r.delete(key)
break
else:
print('代理IP无效哦')
return proxy
#从第三方代理Ip搭建自己的代理IP池方法
def set_proxy():
proxyList[‘'http://proxy.httpdaili.com/apinew.asp?text=true&noinfo=true&sl=10&ddbh=166984367563700473'] while True:
for proxy_url in proxyList:
try:
print (proxy_url)
resp = requests.get(proxy_url, timeout=2)
if resp.status_code == requests.codes.ok:
for ip_port in resp.text.split('\n'):
line = ip_port.strip()
if line and not check(line):
print(line)
redis_r.set('proxy_' + uuid.uuid1().hex, line,REDIS_CASHE)
if "mogumiao" in proxy_url:
time.sleep(5 + random()) # 蘑菇代理5秒
else:
time.sleep(1 + random())
except Exception as e:
print('代理ip服务异常:{}'.format(e))
分析一个网站的技术难度,第一个看技术门槛就是验证码,解决验证码的方法很很多种,我们采用python语言开发的时候,采用python的图像深度识别技术,可以快速轻松解决简单网站验证密码的问题!因为图像识别技术可以轻松的实现吧图片里面的验证码数字和文字提出来,相当于给您把验证码的图片传给我们python图像库函数 自动可以识别里面的验证码值,很轻松的实现破解验证码的问题。但是如果对那种比较难度的二代验证码我们如果在用python图像识别技术就不行了,这个时候就需要AI技术的,训练模型。我当时开发企业工商数据爬虫系统和商标爬虫系统以、专利网爬虫系统、还有全国土地交易爬虫的时候就是我就是用AI模型训练,因为像天某查、企某查、商标网这种的验证码他们采用的是动态特别复杂,简单的Python图像识别无法解决得了。。
关于解决封IP问题,你在爬某网站的时候,对方对IP封得特别厉害,您休想几万或者几十万的去批量采集他里面的数据,这个问题怎么解决呢,其实很简单,遇到这种情况我当时自己建立了代理池,每次发送一个http请求的时候采用一个动态的IP,这样就非常轻松的解决了天某查、淘宝、天猫爬数据的时候的封IP问题。
代理IP池:也许您会问这个代理IP池是做什么,又是怎么实现的呢?我们在爬网站的时候,需要用代理ip不能用我们自己电脑的IP去爬,原因是在你电脑直接运行代码那么爬虫的IP就是你电脑的IP ,如果一直频繁的去采集对方的网站,那么对方会检测到您的IP直接把您的IP列入黑名单导致你以后在也采集不了了。所以我所有的批量采集爬虫都采用代理IP去爬的,python怎么采用代理IP呢?其实很简单就那么一行代码就解决:
resp = requests.get(url, headers=self.headers, timeout=20, proxies=proxy)
我们调用的是 requests的get方法 里面有url、和headers以及 , proxies代理IP设置的参数。
url:就是我们采集的目标网站地址
headers:就是我们模拟访问对方网站时候需要模拟的头参数(这个参数怎么来呢,其实很简单,直接用火狐打开对方网站 查看网络里面有和请求头 那些参数复制过来即可)
Proxies:就是我们的设置我们的代理IP,代理IP是什么意思呢?代理服务器的工作机制很象我们生活中常常提及的代理商,假设你的机器为A机,你想获得的数据由B机提供,代理服务器为C机,那么具体的连接过程是这样的。 首先,A它与C机建立连接把请求发给C,C机接收到A机的数据请求后马上与B机建立连接,下载A机所请求的B机上的数据到本地,再将此数据发送至A机,完成代理任务。这样下载对方网站的数据的是代理服务器,而这个代理服务器IP是随机变动,对方就抓不到是谁一直采集他的数据了。那这个代理ip我们清楚了,这个ip代理池又是什么呢?我们运行我们的python程序的时候,每秒发一个http请求去爬对方网站一次,请求一次需要一个IP,那么这个ip怎么来呢?我们可以网上购买第三方那种ip接口,比如:每10秒中会返回1个IP给我们用,如果我们每次爬数据都先要调取代理IP接口得到IP了再去爬对方网站 那么这个效率和代码质量就低了,因为人家是10秒中才一个IP,您的程序速度和效率就直接卡在因为代理IP接口控制问题了,所以这个时候您需要改进代理IP代码架构,首先每10秒中读取代理IP接口得到的IP 缓存到reis去,并且设置60秒过期,那么这个redis就会形成一个代理IP池了,您的程序代码爬对方网站时候直接从redis读取IP去爬,这样速度就快了,程序架构就优化了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。