如何使用OCR图像识别绕过自如房价的反Spider策略

公元2015 第28个秋天

九月的午后,微风吹动窗纱,从24楼看去远处的白云一朵朵的棉花糖浮在空中,两个街角外教堂上的钟敲响了第十三下。

X坐在桌前,双层的书桌上摆满了各种漫画,电脑旁边的《新世纪福音战士》是他最近从旧物箱里重新翻出来的,望了一眼窗外,闭上眼睛深深地吸了一口气。

他又要换房子了,每到这个季节总是要重新换个地方,换一个身份,周围都是陌生人才会让他有安全感,这样就没有人会发现他的秘密。


打开ZR租房的网站,房源的搜索列表页面映入眼前,适合自己的房子总是自己租不起的。但是X还是要从里面挑选最优的。

Spider是个很不错的选择,Goquery也是个很好的选择

军刀工具 Goquery

采用dom的选择器语法,如果使用Chrome非常容易提取元素的选择器。

chrome 右键->检查->选择需要的dom元素->代码上右键->copy->copy selector

安装

go get github.com/PuerkitoBio/goquery

使用方法

读取页面内容生成Document

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的嘴角露出了微笑,很明显

  1. 图片每次访问都发生变化
  2. 价格的偏移量数据也会发生变化
  3. 为了保证价格每次展示都一样,那么必须有一个跟图片对应的数字转换规则

结论

  1. 无法通过直接转换方式
  2. 寻找这个图片偏移量和价格的转换规则

于是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);
});

通过上面这段代码,整个反爬虫策略就暴露无遗了,其实设计者也是心思巧妙。

OCR 解密之 Tesseract 超立方体

X 在笔记本上写下了如下的话:

  1. 我们有了解密规则
  2. 有了待解密图片
  3. 需要提取图片内容,作为解密的字符串,交由程序处理

于是利用到了另一款军刀工具 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
}

END

ZR如果想使用这种方式来做到反爬虫,其实只是限制了一下反制门槛,但是设计很巧妙。其实本次也是初试Tesseract-OCR这款军刀工具。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spider-Flow是一种基于Python的网络爬虫框架,允许用户非常方便地创建、调度和管理各种网络爬虫任务。通过Spider-Flow,用户可以定制自己的爬虫任务,快速地抓取和处理互联网上的数据。 Spider-Flow具有以下几个特点和功能: 1. 强大的可视化界面:Spider-Flow提供了一个直观且友好的可视化界面,用户可以通过拖拽、连接图形化组件来创建和管理爬虫任务,无需编写复杂的代码。 2. 多线程调度:Spider-Flow基于多线程技术,可以同时运行多个爬虫任务,提高爬取效率和速度。 3. 可扩展性:Spider-Flow支持插件式开发,用户可以根据自己的需求编写或安装插件,扩展框架的功能。 4. 数据清洗和处理:Spider-Flow提供了丰富的数据处理组件和函数库,用户可以对爬取到的数据进行清洗、筛选、转换等操作,方便地提取有用信息。 5. 数据导出和存储:Spider-Flow支持将爬取到的数据导出到多种格式,如CSV、Excel、数据库等,方便用户进行进一步的分析和使用Spider-Flow的使用步骤如下: 1. 安装配置:首先,用户需要安装Python和Spider-Flow框架,并进行相应的配置。 2. 创建项目:在Spider-Flow界面中,用户可以创建一个新的爬虫项目,并设置相关的参数和配置。 3. 编辑爬虫任务:用户可以从组件库中选择需要的组件,然后将其拖拽到任务编辑区域,并设置相应的参数和连接。 4. 编辑数据处理:用户可以在爬虫任务完成后,通过添加数据处理组件来清洗和处理爬取到的数据。 5. 运行任务:设置好全部的任务和参数后,用户可以点击运行按钮,启动爬虫任务的执行。 6. 导出和存储数据:当爬虫任务完成后,用户可以选择将数据导出到指定的格式,或直接存储到数据库中。 总之,Spider-Flow是一种方便快捷的网络爬虫框架,用户可以通过简单的拖拽和配置,创建并管理自己的爬虫任务,并方便地处理和存储爬取到的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值