【Python3爬蟲】常見反爬蟲措施及解決辦法(三)

 上一篇博客的末尾說到全網代理IP的端口號是通過加密混淆的,而這一篇博客就將告訴你如何破解!若是以爲有用的話,不妨點個推薦哦~javascript

 

1、全網代理IP的JS混淆

首先進入全網代理IP,打開開發者工具,點擊查看端口號,看起來貌似沒有什麼問題:html

若是你已經爬取過這個網站的代理,你就會知道事情並不是這麼簡單。若是沒爬過呢?也很簡單,點擊鼠標右鍵而後查看網頁源代碼,搜索」port「,能夠找到以下內容:java

很明顯這不是網頁上顯示的端口號了,那咱們要怎麼才能獲得真正的端口號呢?正則表達式

解決辦法:

 首先須要找到一個JS文件:http://www.goubanjia.com/theme/goubanjia/javascript/pde.js?v=1.0,點開後能夠看到以下內容:函數

這麼複雜的JS代碼看得人頭都大了,不過咱們發現這個JS代碼是一個eval函數,那咱們能不能把它解碼一下呢?這時候你須要一個工具--腳本之家在線工具,把這些JS代碼複製進去:工具

 而後點擊解碼:網站

 

仍是一個eval函數,因此再次解碼:this

到這一步,已經比最開始的代碼簡潔多了,可是還易讀性仍是不好,因此咱們須要先格式化一下:加密

var _$ = [
"\x2e\x70\x6f\x72\x74",
"\x65\x61\x63\x68",
"\x68\x74\x6d\x6c",
"\x69\x6e\x64\x65\x78\x4f\x66",
"\x2a",
"\x61\x74\x74\x72",
"\x63\x6c\x61\x73\x73",
"\x73\x70\x6c\x69\x74",
"\x20",
"",
"\x6c\x65\x6e\x67\x74\x68",
"\x70\x75\x73\x68",
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x5a",
"\x70\x61\x72\x73\x65\x49\x6e\x74",
"\x6a\x6f\x69\x6e",
""
];
$(function() {
$(_$[0])[_$[1]](function() {
var a = $(this)[_$[2]]();
if (a[_$[3]](_$[4]) != -0x1) {
return;
}
var b = $(this)[_$[5]](_$[6]);
try {
b = b[_$[7]](_$[8])[0x1];
var c = b[_$[7]](_$[9]);
var d = c[_$[10]];
var f = [];
for (var g = 0x0; g < d; g++) {
f[_$[11]](_$[12][_$[3]](c[g]));
}
$(this)[_$[2]](window[_$[13]](f[_$[14]](_$[15])) >> 0x3);
} catch (e) {}
});
});url

能夠看到有一個列表和一個函數,而這個函數應該就是混淆的函數了,可是這列表裏的數據都是十六進制的,還須要解碼一下(這一步能夠用Python來作):

_ = ["\x2e\x70\x6f\x72\x74", "\x65\x61\x63\x68", "\x68\x74\x6d\x6c", "\x69\x6e\x64\x65\x78\x4f\x66", "\x2a",
"\x61\x74\x74\x72", "\x63\x6c\x61\x73\x73", "\x73\x70\x6c\x69\x74", "\x20", "", "\x6c\x65\x6e\x67\x74\x68",
"\x70\x75\x73\x68", "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x5a", "\x70\x61\x72\x73\x65\x49\x6e\x74",
"\x6a\x6f\x69\x6e", ""
]
_ = [i.encode('utf-8').decode('utf-8') for i in _]
print(_)
# ['.port', 'each', 'html', 'indexOf', '*', 'attr', 'class', 'split', ' ', '', 'length', 'push', 'ABCDEFGHIZ', 'parseInt', 'join', '']

而後把這個列表裏的元素添加到上面的JS函數中,能夠獲得以下結果:

 1 $(function() {
 2   $(".port")["each"](function() {
 3     var a = $(this)["html"]();
 4     if (a["indexOf"]("*") != -0x1) {
 5       return;
 6     }
 7     var b = $(this)["attr"]("class");
 8     try {
 9       b = b["split"](" ")[0x1];
10       var c = b["split"]("");
11       var d = c["length"];
12       var f = [];
13       for (var g = 0x0; g < d; g++) {
14         f["push"]("ABCDEFGHIZ"["indexOf"](c[g]));
15       }
16       $(this)["html"](window["parseInt"](f["join"]("")) >> 0x3);
17     } catch (e) {}
18   });
19 });

能夠看到這段JS代碼就是先找到每一個端口節點,而後把端口的class值提取出來,再進行拆分字符串,而後獲取每一個字母在」ABCDEFGHIZ「中的下標值,並把這些值拼接成字符串,再轉爲整型數據,最後把這個整型數據向右移3位。好比」GEA「對應的下標組成的字符串是」640「,轉爲整型數據後向右移3位的結果就是80,也就是真實的端口值了。最後附上用Python解密端口號的代碼:

1 et = etree.HTML(html)
2 port_list = et.xpath('//*[contains(@class,"port")]/@class')
3 for port in port_list:
4     port = port.split(' ')[1]
5     num = ""
6     for i in port:
7         num += str("ABCDEFGHIZ".index(i))
8     print(int(num) >> 3)

 

2、用圖片代替文字

以前就有人評論說有的網站使用圖片代替文字以實現反爬蟲,而後我此次就找到了一個網站--新蛋網,隨意點擊一個商品查看一下:

打開開發者工具,而後點擊查看價格,想不到價格竟然是經過圖片來顯示的:

解決辦法:

 我找到兩個能夠獲得價格的辦法,一個簡單的,一個難一點的。簡單的方法是用正則表達式,由於在源碼中的其餘地方是包含商品的基本信息的,好比名稱和價格,因此咱們可使用正則表達式進行匹配,代碼以下:

1 import re
2 import requests
3 
4 
5 url = "https://www.newegg.cn/Product/A36-125-E5L.htm?neg_sp=Home-_-A36-125-E5L-_-CountdownV1"
6 res = requests.get(url)
7 result = re.findall("name:'(.+?)', price:'(.+?)'", res.text)
8 print(result)

難一點的方法是把圖片下載到本地以後進行識別,因爲這個圖片的清晰度很高,也沒有扭曲或者加入干擾線什麼的,因此能夠直接使用OCR進行識別。可是用這種方法的話須要安裝好Tesseract-OCR,這個工具的安裝過程仍是比較麻煩的。用這種方法破解的代碼以下:

 1 import requests
 2 import pytesseract
 3 from PIL import Image
 4 from lxml import etree
 5 
 6 
 7 url = "https://www.newegg.cn/Product/A36-125-E5L.htm?neg_sp=Home-_-A36-125-E5L-_-CountdownV1"
 8 res = requests.get(url)
 9 et = etree.HTML(res.text)
10 img_url = et.xpath('//*[@id="priceValue"]/span/strong/img/@src')[0]
11 with open('price.png','wb') as f:
12      f.write(requests.get(img_url).content)
13 pytesseract.pytesseract.tesseract_cmd = 'E:/Python/Tesseract-OCR/tesseract.exe'
14 text = pytesseract.image_to_string(Image.open('price.png'))
15 print(text)
16 # 6999.00
相關文章
相關標籤/搜索