爬取全網代理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給決議了,埠還加密著呢,但是考慮到文章太長,閱讀效果不佳,于是就放在下一篇,
最新爬取全網代理IP【隱藏標簽混淆+埠加密】(二)
剛接觸這塊知識,代碼寫的不好,還請諒解,如果有理解錯誤的,也請大佬在評論區指出來,非常感謝!
以上就是剔除混淆在其中的隱藏標簽的所有內容了,點贊收藏加評論是最大的支持哦!
📑撰寫不易,轉載請注明出處,如有侵權,請聯系我!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/157359.html
標籤:其他
上一篇:多執行緒并發編程的基本問題
下一篇:樹形DP(鄰接表)
