爬取全网代理IP【隐藏标签混淆+端口加密】(一)
起因:这两天,在学习Scrapy爬取某家租房信息时,被频繁封IP,去网上找免费的代理IP,时间长,还要测试有效性,去购买套餐,又不值得,毕竟只是学习。于是,就打算搭建一个代理池,在网上爬取公开免费的代理IP,并进行维护,做有效性检测。
前言:在爬取前几家(西拉代理、泥马代理等)公开的免费代理IP时,都没问题,很顺利的就爬取下来了,但在爬取全网代理时,让我的脚步,一度放慢,为什么呢?
【完整代码点击下载】
坐好坐好,开始表演啦~~🐱🏍
一、混淆在其中的隐藏标签
1.分析对方
先放上其全网代理官网地址:http://www.goubanjia.com/
老练的,按F12,复制xpath,进行提取…等等,等等,我们看下图,发现它多出一些p标签来了【达到了混淆的目的】,这对我们可不是好事。
怎么办呢?我们仔细看看这些混淆在其中的p
标签,发现都有一个共同的一个特点,就是混淆值的下一个就是真实值;即该p
标签跟p
标签下一个标签的值是相等的。【突破的关键】
如下:
<td class="ip">
<p style='display: none;'>2</p> //<----
<span>2</span>
<p style='display: none;'>7.</p> //<----
<span>7.</span>
<span style='display: inline-block;'></span>
<span style='display: inline-block;'>19</span>
<span style='display: inline-block;'>2.</span>
<p style='display: none;'>20</p> //<----
<span>20</span>
<span style='display: inline-block;'>2</span>
<p style='display: none;'>.</p> //<----
<span>.</span>
<div style='display: inline-block;'>5</div>
<div style='display: inline-block;'>7</div>:
<span class="port HCAAA">8174</span>
</td>
2.首次出征
了解到这些就好办了,解决方法:
我们直接将td
标签下的值都获取下来,然后进行校验,校验思路,我们了解混淆的值
跟下一个值
是一样的,那拿它作为我们的校验条件,遍历里面的值,将遍历的值跟后一个值进行匹配,如果相同,删除当前遍历的值,但我们看看下面这个td
标签
<td class="ip">
<span style='display:inline-block;'>2</span>
<span style='display:inline-block;'>2</span>
<p style='display: none;'>0.</p>
<span>0.</span>
<span style='display:inline-block;'>1</span>
<span style='display:inline-block;'>67</span>
<span style='display:inline-block;'>.4</span>
<div style='display:inline-block;'>2</div>
<div style='display:inline-block;'></div>
<p style='display: none;'></p>
<span></span>
<div style='display:inline-block;'>.1</div>
<p style='display: none;'>5</p>
<span>5</span>:
<span class="port GEZEE">8823</span>
</td>
我们使用刚才那个校验规则,来校验这个,第一个值(是2)跟第二个值(也是2)相同,删除第一个,但实际,我们并不是要删除这个,而是p
标签下的字符,所以继续优化校验规则。
3.二次再战
我们知道xpath
是可以通过文本获取它的内容。如果输入的文本没有找到相应的值则会返回空,如//tr[1]/td[1]/p[text()="2"]/text()
,其中text()="2"
的2
就是第一个校验规则匹配筛选出的相同值,将其放入到xpath语法中,通过文本查找它的值,如果有值,说明在该td
标签中有该值的p
标签,反之该值就不是p
标签的值。
梳理下,校验规则,先获取
td
下的所有值,并进行遍历,第一次筛选,如果第一个值跟下一个值相同,进入第二次筛选,如果该值能通过p
标签的文本查找到相同文本,说明td
标签下确实有该值的p
标签,并将其删除,即删除p
标签的值,留下真实(有效)值。
4.局部出兵策略
**校验规则
**代码如下:
# 获取所有的tr标签
tr_list = html_str.xpath('//*[@id="services"]/div/div[2]/div/div/div/table/tbody/tr')
for tr in tr_list:
# TODO 1.解析ip值
tr_ip = tr.xpath('./td[1]//text()') # 获取td[1]下的所有值
tr_ip_list = list(enumerate(tr_ip))
y = 0
while True:
if y + 1 < len(tr_ip_list):
# 第一个校验条件,如果两值相等 -->可疑对象
if tr_ip_list[y][1] == tr_ip_list[y + 1][1]:
# 第二个校验条件,如果成立,即已确定是混淆值,进行删除当前遍历的值
if tr.xpath(f'./td[1]/p[text()="{tr_ip_list[y][1]}"]/text()'):
# print('在p标签中,文本查找返回值:', tr.xpath(f'./td[1]/p[text()="{tr_ip_list[y][1]}"]/text()')[0], '并等于下一个值:', tr_ip_list[y + 1][1], '-->删除该p标签值:',tr_ip_list[y])
del tr_ip_list[y] # 删除当前值
else:
# print('在p标签中,文本查找返回值:', tr.xpath(f'./td[1]/p[text()="{tr_ip_list[y][1]}"]/text()'), '不等于下一个值', tr_ip_list[y + 1][1],'>>>>>>可疑对象关系解除<<<<<<')
pass
else:
break
y += 1
ip = "".join([i[1] for i in tr_ip_list])
print('IP:', ip, '\n', "=" * 100)
如果不是很懂的,可以取消打印注释,看看控制台效果。
【扩展】第二个校验规则还可以这么写,我们再仔细看看其p
标签,发现都有共同的 display: none;
属性。所以,第二个条件我们可以这么判断,通过文本去获取它的属性,如果属性为display: none;
,即说明该值是在p
标签中。(这个就不做代码演示了,跟上面的基本一样。)
到这,我们就将这些混淆在其中的隐藏元素标签给剔除了。
5.准备发起总攻
结束了?并没呢,我们只是将其ip给解析了,端口还加密着呢,但是考虑到文章太长,阅读效果不佳,于是就放在下一篇。
刚接触这块知识,代码写的不好,还请谅解,如果有理解错误的,也请大佬在评论区指出来,非常感谢!
以上就是剔除混淆在其中的隐藏标签的所有内容了,点赞收藏加评论是最大的支持哦!
📑编写不易,转载请注明出处,如有侵权,请联系我!