在这两天的个人使用中,增加了一些接口并发现了一些功能完善建议,看下是否合理。
新增接口
1. 获取最优代理接口
爬取过程中我不并想要随机代理,即使我已经把校验代理可用性的周期已经改为了10s,但还是有很多的随机代理连续不可用的情况,导致抓取失败率较高。我更希望每次获取最优代理,在代理有效期内最大程度地利用此代理。选取标准基于 check_count
以及 fail_count
的差值。
核心语句:choice = max(item_list, key=lambda d: json.loads(d)['check_count'] - json.loads(d)['fail_count'])
2. 更新 check_count
接口以及更新 fail_count
接口
当前check_count仅仅在校验过程中发生更新。但由于我新增了最优代理接口,希望在实际使用代理过程中可以实时更新其 check_count
以及 fail_count
,从而可以持续保持代理的最优性。
核心语句:
def update_check_count(self, proxy_str):
self.db.changeTable(self.useful_proxy_queue)
value = self.db.get(proxy_str)
if value:
dic = json.loads(value)
dic['check_count'] += 1
value = json.dumps(dic)
try:
self.db.update(proxy_str, value)
return {'code': 1, 'msg': 'success', 'proxy': dic['proxy'], 'check_count': dic['check_count']}
except Exception as e:
print(e)
return {'code': 0, 'msg': 'update failed'}
else:
return {'code': 0, 'msg': 'proxy is not exist'}
def update_fail_count(self, proxy_str):
self.db.changeTable(self.useful_proxy_queue)
value = self.db.get(proxy_str)
if value:
dic = json.loads(value)
dic['fail_count'] += 1
value = json.dumps(dic)
try:
self.db.update(proxy_str, value)
return {'code': 1, 'msg': 'success', 'proxy': dic['proxy'], 'fail_count': dic['fail_count']}
except Exception as e:
print(e)
return {'code': 0, 'msg': 'update failed'}
else:
return {'code': 0, 'msg': 'proxy is not exist'}
功能建议
1. fail_count
的变化逻辑
在 /proxy_pool/ProxyHelper/ProxyUtil.py
中,校验成功则 check_count+=1, if fail_count>0: fail_count-=1
; 校验失败则 check_count+=1, fail_count+=1
。可以看到, check_count
代表校验次数没有问题,而 fail_count
既承担了失败数的角色,又承担了成功数的角色,我认为模糊了此字段,不能达到应有的效果。比如说,我想找一个最优代理,自然是看成功次数或是成功率,但由于 fail_count
在校验成功反而会减1,那么我无法通过这两个字段得到确切的成功次数或是成功率。也就是说,在原有逻辑中,我想找最优代理,只能从 fail_count
最小的代理中去找,但这样是不足以找最优代理的,比如一个 fail_count=0, check_count=10
的代理可能代表成功10次,也可能代表成功5次失败5次,是一个模糊的组合。
改进逻辑:
要么增加一个新字段 suc_count
代表成功数,要么在校验成功时 fail_count
不自减,这样字段组合就可以唯一性确定代理的校验情况。我采用的是后者。见:
def checkProxyUseful(proxy_obj):
"""
检测代理是否可用
:param proxy_obj: Proxy object
:return: Proxy object, status
"""
if validUsefulProxy(proxy_obj.proxy):
# 检测通过 更新proxy属性
proxy_obj.check_count += 1
proxy_obj.last_status = 1
proxy_obj.last_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# if proxy_obj.fail_count > 0:
# proxy_obj.fail_count -= 1
return proxy_obj, True
else:
proxy_obj.check_count += 1
proxy_obj.last_status = 0
proxy_obj.last_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
proxy_obj.fail_count += 1
return proxy_obj, False
以上新增功能及建议均不影响原有功能,可以讨论下合理性以及必要性。
9条答案
按热度按时间gjmwrych1#
3q, 这就相当于某种评分机制,代理某次请求不通了还保留认为其可能为恢复 . 其实在实际使用中,代理一次不通直接就扔掉,拿下一个,代理本身失效就快,代码里面默认
fail_count
大于0就扔掉的,设计之初就不想加入这个机制,因为这样会到整个池的ip有部分是不确定100%能用的,保留不好的代理来增加池子数量并不好。如果说要筛选最优代理的话,应该是从响应速度和有效时长来考虑,对垃圾代理零容忍是我本身初衷,但是后面很多要求保留某次请求失败的代理才加入
fail_count
这个概念,后面应该不会在这方面往下扩展,pb3skfrl2#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
mum43rcc3#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
可以在
/proxy_pool/Schedule/UsefulProxyCheck.py
中自定义FAIL_COUNT
为你认为合适的值,在fail_count
大于此值时会删除此代理。源代码中FAIL_COUNT
为0。dfddblmv4#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
可以在
/proxy_pool/Schedule/UsefulProxyCheck.py
中自定义FAIL_COUNT
为你认为合适的值,在fail_count
大于此值时会删除此代理。源代码中FAIL_COUNT
为0。可是假设这个ip检测时一直可用,到之后max就算fail_count不断增加,也会造成使用的一直是此ip,即使爬虫已经封闭了此ip的访问
sg3maiej5#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
可以在
/proxy_pool/Schedule/UsefulProxyCheck.py
中自定义FAIL_COUNT
为你认为合适的值,在fail_count
大于此值时会删除此代理。源代码中FAIL_COUNT
为0。可是假设这个ip检测时一直可用,到之后max就算fail_count不断增加,也会造成使用的一直是此ip,即使爬虫已经封闭了此ip的访问
针对这个我在第一个comment里写了,我新增了主动更新
check_count
和fail_count
接口,在爬虫中植入了此代理中间件,所以check_count
和fail_count
是随着爬虫进行而实时更新的,并不是只在校验代理时更新,所以如果某代理失效了,其fail_count
会立刻剧增,从而不会出现在长时间内都是同一代理的情况。daolsyd06#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
可以在
/proxy_pool/Schedule/UsefulProxyCheck.py
中自定义FAIL_COUNT
为你认为合适的值,在fail_count
大于此值时会删除此代理。源代码中FAIL_COUNT
为0。可是假设这个ip检测时一直可用,到之后max就算fail_count不断增加,也会造成使用的一直是此ip,即使爬虫已经封闭了此ip的访问
针对这个我在第一个comment里写了,我新增了主动更新
check_count
和fail_count
接口,在爬虫中植入了此代理中间件,所以check_count
和fail_count
是随着爬虫进行而实时更新的,并不是只在校验代理时更新,所以如果某代理失效了,其fail_count
会立刻剧增,从而不会出现在长时间内都是同一代理的情况。可以咨询下这两个中间代理是放在哪里的嘛..因为我找了一圈发现找不到,谢谢🙏
5anewei67#
我觉得最优代理这个概念是可取的,不过max取值,并且更新,不会造成一段时间内取到得都是同一个ip代理嘛,有此疑惑
可以在
/proxy_pool/Schedule/UsefulProxyCheck.py
中自定义FAIL_COUNT
为你认为合适的值,在fail_count
大于此值时会删除此代理。源代码中FAIL_COUNT
为0。可是假设这个ip检测时一直可用,到之后max就算fail_count不断增加,也会造成使用的一直是此ip,即使爬虫已经封闭了此ip的访问
针对这个我在第一个comment里写了,我新增了主动更新
check_count
和fail_count
接口,在爬虫中植入了此代理中间件,所以check_count
和fail_count
是随着爬虫进行而实时更新的,并不是只在校验代理时更新,所以如果某代理失效了,其fail_count
会立刻剧增,从而不会出现在长时间内都是同一代理的情况。可以咨询下这两个中间代理是放在哪里的嘛..因为我找了一圈发现找不到,谢谢🙏
这两个更新接口我在第一个comment里面贴了代码。中间件逻辑很简单,就是在爬虫中针对每一次请求都更新
check_count
,如果请求失败就更新fail_count
,并更换代理。我的爬虫是基于scrapy的,贴一下我的代理中间件:ilmyapht8#
get
1cosmwyk9#
我现在使用了一种暴力的方法..一旦status_code 不在[200, 300)范围内,直接delete,就不造成重复了