Skip to content

美团电影爬虫心得 #11

@timest

Description

@timest

美团电影频道的数字都是通过在背景图片上进行偏移获得最终数字。
image

image

因为数字的图形是固定的,且每张都是10 * 16像素,可以实现爬取每个数字的图片保存在本地,然后通过爬取的内容根据偏移地址进行计算图片位置,进行切割,并与本地单张数字进行对比,即可获得当前数字。
后面的代码片段用的是go语言。如果用python的话,直接用pytesser进行数字识别。

解决方案

图片采集

先对美团的数字图片(保存名为meituan.png)进行切割并保存10个数字和一个小数点的图片。每张图片像素是10*16。

func main() {
    img := loadImage("meituan.png")
    n := 1
    for x := 0; x < 100; x += 10 {
        for y := 0; y < 96; y += 16 {
            dd := img.(*image.NRGBA).SubImage(image.Rect(x, y, x+10, y+16))
            saveImage(fmt.Sprintf("pic/%d.png", n), dd)
            n++
        }
    }
}

func loadImage(path string) image.Image {
    f, err := os.Open(path)
    if err != nil {
        log.Fatal(err)
    }
    img, _, err := image.Decode(f)
    if err != nil {
        log.Fatal(err)
    }
    return img
}

func saveImage(path string, img image.Image) {
    i, _ := os.Create(path)
    defer i.Close()
    png.Encode(i, img)
}

image

分析

每个图片数字都是通过backgroud-position进行定位。所以我们只需要两部即可获得数字:

  • 下载数字图片,图片并非固定 100 * 96 ,但是最终切割后的图片是 10 * 16
  • 切割后和进行对比

切割后的照片,我们传入match函数即可获得最终数字结果:

func match(img image.Image) string {
    for x:=0; x<=10; x++ {
        i := loadImage(fmt.Sprintf("pic/%d.png", x))
        d := diff(img, i)
        if d > 0.9 {
            if x == 10 {
                return "."
            }
            return strconv.Itoa(x)
        }
        //log.Infof("%d diff:%f",x, d)
    }
    return ""
}

// 对比两张图片的相似度
func diff(i1, i2 image.Image) float64 {
    r1 := i1.Bounds()
    r2 := i2.Bounds()
    minX := math.Min(float64(r1.Max.X), float64(r2.Max.X))
    minY := math.Max(float64(r1.Max.Y), float64(r2.Max.Y))
    c := 0
    sum := 0
    for x := 0; x < int(minX); x++ {
        for y := 0; y < int(minY); y++ {
            if i1.At(x, y) == i2.At(x, y) {
                c++
            }
            sum++
        }
    }
    //log.Info(c, sum, float64(c)/float64(sum))
    return float64(c)/float64(sum)
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions