公元2015 第28個秋天html
九月的午後,微風吹動窗紗,從24樓看去遠處的白雲一朵朵的棉花糖浮在空中,兩個街角外教堂上的鐘敲響了第十三下。git
X坐在桌前,雙層的書桌上擺滿了各類漫畫,電腦旁邊的《新世紀福音戰士》是他最近從舊物箱裏從新翻出來的,望了一眼窗外,閉上眼睛深深地吸了一口氣。github
他又要換房子了,每到這個季節老是要從新換個地方,換一個身份,周圍都是陌生人才會讓他有安全感,這樣就沒有人會發現他的祕密。chrome
打開ZR租房的網站,房源的搜索列表頁面映入眼前,適合本身的房子老是本身租不起的。可是X仍是要從裏面挑選最優的。數組
Spider是個很不錯的選擇,Goquery也是個很好的選擇安全
採用dom的選擇器語法,若是使用Chrome很是容易提取元素的選擇器。dom
chrome 右鍵->檢查->選擇須要的dom元素->代碼上右鍵->copy->copy selector
go get github.com/PuerkitoBio/goquery
讀取頁面內容生成Documentide
res, e := http.Get(url); if e != nil { // e } defer res.Body.Close() doc, e := goquery.NewDocumentFromReader(res.Body) if e != nil { // e }
使用選擇器選擇頁面內容工具
doc.Find("#houseList > li").Each(func(i int, selection *goquery.Selection) { // 房屋名稱 houseName := selection.Find("div.txt > h3 > a").Text() }
或者可使用直接選取的方式測試
// 獲取經緯度 houseLat, _ := doc.Find("#mapsearchText").Attr("data-lat") houseLng, _ := doc.Find("#mapsearchText").Attr("data-lng")
常見的頁面元素價格,是相似<span>$5880</span>
這種實現方式,可是ZR採用了另一種。
ta的價格是經過CSS樣式表對背景圖片的偏移來實現的,例如價格¥2690
的實現:
<span style="background-position:1000px" class="num rmb">¥</span> <span style="background-position:-90px" class="num"></span> <span style="background-position:-210px" class="num"></span> <span style="background-position:-0px" class="num"></span> <span style="background-position:-240px" class="num"></span>
圖片地址是
images/price/0fcc0d83409c547d3a9d038cc7808fa3s.png
圖片的內容是
6532148907
那麼針對如上的狀況X提出一個方案:根據偏移量來轉換獲得價格
這個思路是對的,可是仔細測試後,發現每次訪問,圖片的地址都會發生變化,對應的圖片裏面的數字的排序也會發生變化。
這時X的嘴角露出了微笑,很明顯
結論
因而X經過Chrome的search找到了價格元素修改的js代碼
var ROOM_PRICE = {"image":"//xxxx.com/phoenix/pc/images/price/0fcc0d83409c547d3a9d038cc7808fa3s.png","offset":[[3,7,0,8],[3,7,0,8],[2,3,0,8],[2,3,7,8],[2,0,2,8],[3,7,2,8],[2,2,7,8],[2,2,2,8],[3,6,7,8],[3,6,7,8],[2,8,2,8],[2,8,7,8],[3,7,0,8],[2,4,7,8],[2,5,7,8],[2,8,7,8],[2,5,7,8],[2,3,7,8]]}; // 這一段不用看了,其實就是將圖片上的字符,按照上面ROOM_PRICE的規則,按照數組的索引取出來便可 $('#houseList p.price').each(function(i){ var dom = $(this); if(!ROOM_PRICE['offset'] || !ROOM_PRICE['offset'][i]) return ; var pos = ROOM_PRICE['offset'][i]; for(i in pos){ var inx = pos.length -i -1; var seg = $('<span>', {'style':'background-position:-'+(pos[inx]*offset_unit)+'px', 'class':'num'}); dom.prepend(seg); } var seg = $('<span>', {'style':'background-position:1000px', 'class':'num rmb'}).html('¥'); dom.prepend(seg); });
經過上面這段代碼,整個反爬蟲策略就暴露無遺了,其實設計者也是心思巧妙。
X 在筆記本上寫下了以下的話:
因而利用到了另外一款軍刀工具 Tesseract
Tesseract是一個光學字符識別引擎,支持多種操做系統。Tesseract是基於Apache許可證的自由軟件,自2006 年起由Google贊助開發。2006年,Tesseract被認爲是最精準的開源光學字符識別引擎之一。
Tesseract 翻譯過來是 超立方體
這裏是Wiki :https://github.com/tesseract-...
Mac 下的安裝很簡單
brew install tesseract
安裝完畢以後能夠解析下試試
➜ go tesseract ~/Desktop/7d9a5bb074a89f93a5b4e82bea5dc872s.png stdout --psm 6 2436851907
安裝Go的package
go get -v -t github.com/otiai10/gosseract
直接上代碼了,調用很方便
package ocr import ( "fmt" "net/http" "os" "github.com/otiai10/gosseract" "io/ioutil" "io" "bytes" ) func Parse(imageUrl string)(string) { f, _ := os.Create("s.png") defer f.Close() resp, _ := http.Get(imageUrl) defer resp.Body.Close() pic, _ := ioutil.ReadAll(resp.Body) io.Copy(f, bytes.NewReader(pic)) client := gosseract.NewClient() defer client.Close() client.SetImage("./s.png") text, e := client.Text() if e != nil { fmt.Println("error") } return text }
最終,使用OCR解密了圖片內容,再經過轉換才的到了真正的價格
{ "_id" : ObjectId("5b88dfa8644d03deebc6ba6a"), "name" : "天通苑中苑4居室-南臥", "image" : "http://img.xxxx.com/pic/house_images/g2m1/M00/66/82/ChAFB1uGM-KAZfN6AAQ6qYhGUtc084.JPG_C_264_198_Q80.jpg", "price" : "2290", "url" : "http://www.xxxx.com/z/vr/61676366.html", "size" : "13 ㎡", "floor" : "5/6層", "room" : "4室1廳", "loc" : [ "40.077562", "116.432684" ], "toilet" : 0, "balcony" : 1 } /* 2 */ { "_id" : ObjectId("5b88dfa9644d03deebc6ba6f"), "name" : "天通苑中苑4居室-南臥", "image" : "http://img.xxxx.com/pic/house_images/g2m1/M00/4F/6E/ChAFBlt9cXaAY-38AARyYlEU6S4611.JPG_C_264_198_Q80.jpg", "price" : "2430", "url" : "http://www.xxxx.com/z/vr/61663763.html", "size" : "11.8 ㎡", "floor" : "5/10層", "room" : "4室1廳", "loc" : [ "40.077562", "116.432684" ], "toilet" : 0, "balcony" : 1 } /* 3 */ { "_id" : ObjectId("5b88dfa9644d03deebc6ba74"), "name" : "天通苑本三區4居室-南臥", "image" : "http://img.xxxx.com/pic/house_images/g2m1/M00/5A/E5/ChAFBluBaA-APjRgAASBBLkpT0w953.JPG_C_264_198_Q80.jpg", "price" : "2790", "url" : "http://www.xxxx.com/z/vr/61666427.html", "size" : "25.5 ㎡", "floor" : "6/6層", "room" : "4室1廳", "loc" : [ "40.066064", "116.426734" ], "toilet" : 0, "balcony" : 1 }
ZR若是想使用這種方式來作到反爬蟲,其實只是限制了一下反制門檻,可是設計很巧妙。其實本次也是初試Tesseract-OCR
這款軍刀工具。