背景圖片反爬之自如租房?jī)r(jià)格抓取

此次我們要練手的網(wǎng)站是自如租房,自如租房網(wǎng)對(duì)租房的價(jià)格進(jìn)行了CSS背景圖片反爬,它把一張有隨機(jī)0-9數(shù)字的圖片作為背景圖片,然后通過(guò)background-position樣式來(lái)映射數(shù)字,我們需要找到背景反爬的規(guī)律以及通過(guò)OCR識(shí)別出背景圖片中的數(shù)字。

目標(biāo)分析

頁(yè)面效果

可以發(fā)現(xiàn)同一個(gè)背景位置偏移量對(duì)應(yīng)的映射的價(jià)格數(shù)字是一樣的,而且行內(nèi)樣式里有背景圖片的鏈接,并且background-size20px,我們下載背景圖片然后分析背景圖片與背景位置偏移量的映射關(guān)系:
背景圖片大小

背景圖片

可以發(fā)現(xiàn)圖片大小是300x28,圖片里的數(shù)字是8670415923,我們首先需要把圖片的寬度等比例縮小到20px,縮放后得到的規(guī)格是214.281x20,每個(gè)數(shù)字的大小214.281/10 = 21.4281,保留一位小數(shù)就是21.4px,再看網(wǎng)頁(yè)源代碼上的背景偏移量數(shù)字2的偏移量是-171.2px,171.2/21.4 = 8 因?yàn)榈谝粋€(gè)是的偏移量為0,所以數(shù)字2對(duì)應(yīng)的應(yīng)該是8+1 = 9 ,映射到圖片上第9個(gè)數(shù)字,我們發(fā)現(xiàn)正是數(shù)字2,數(shù)字5數(shù)字0的背景偏移量分別是-128.4px-64.2px128.4/21.4 +1 = 7以及64.2/21.4 +1 = 4,映射到圖片上第7個(gè)數(shù)字和第4個(gè)數(shù)字,我們發(fā)現(xiàn)正是數(shù)字5數(shù)字0,找到了背景反爬偏移量的映射規(guī)律,我們需要識(shí)別背景圖片里的數(shù)字,我們可以使用Tesseract來(lái)識(shí)別,背景圖片里的數(shù)字沒(méi)有干擾線以及噪點(diǎn)所以識(shí)別出來(lái)基本上是100%準(zhǔn)確率。

破解思路

先下載背景圖片,用Tesseract來(lái)識(shí)別背景圖片里的數(shù)字,再提取網(wǎng)頁(yè)源代碼中背景圖片的偏移量,最后根據(jù)我們得出的規(guī)律計(jì)算出正確的數(shù)字。

'''
時(shí)間原因只抓1頁(yè)
'''
import requests
from urllib.request import urlretrieve
import re
import pytesseract
from PIL import Image
from lxml import etree

# 請(qǐng)求的url
url = "http://sz.ziroom.com/z/"

headers = {
    'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
    }


response = requests.get(url, headers=headers)

html = etree.HTML(response.text)
bg_img_info = html.xpath('//div[@class="price"]/span[@class="num"]/@style')[0]
if len(re.findall(r'background-image: url\((.*?)\)',bg_img_info))>0:
    bg_img_url = "http:" + re.findall(r'background-image: url\((.*?)\)',bg_img_info)[0]
    info = html.xpath('//div[@class="Z_list-box"]/div[@class="item"]')
    for i in info:  
        title = i.xpath('.//h5/a/text()')[0]
        area = i.xpath('.//div[@class="desc"]/div[1]/text()')[0]
        location = i.xpath('.//div[@class="desc"]/div[@class="location"]/text()')[0].replace('\n',"").replace('\t',"").replace(' ',"")
        tag = ",".join(i.xpath('.//div[@class="tag"]/span/text()'))
        position_list = [re.findall(r'background-position: -(.*?)px',j)[0] for j in i.xpath('.//div[@class="price"]/span[@class="num"]/@style')]
        price_list = [int(float(i)/21.4 + 1) for i in position_list]
        urlretrieve(bg_img_url,'background_img.png')
        image = Image.open('background_img.png')
        text = pytesseract.image_to_string(image)
        num = [i for i in text]
        price = "¥" + "".join([num[i-1] for i in price_list]) + "/月起"
        print(title, area, location, tag,price)
else:
      print("提取背景圖片鏈接出錯(cuò)!")

結(jié)果

運(yùn)行結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容