公元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
这款军刀工具。