<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python處理超強(qiáng)反爬(TSec防火墻+CSS圖片背景偏移定位)

          共 6896字,需瀏覽 14分鐘

           ·

          2021-11-28 12:56

          點(diǎn)擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進(jìn)行關(guān)注

          回復(fù)“書籍”即可獲贈(zèng)Python從入門到進(jìn)階共10本電子書

          松下問童子,言師采藥去。

          大家好,我是小小明,今天看到一個(gè)網(wǎng)站:

          太神奇了,對(duì)于每個(gè)數(shù)字都用css背景圖片裁切得到一張小圖進(jìn)行顯示??梢源_定的是每個(gè)數(shù)字的圖片大小是8*17。

          今天我們就一起玩玩。

          開始測試

          先嘗試用request讀取數(shù)據(jù),結(jié)果獲得一大堆極度混淆的JS的代碼。然后嘗試用selenium訪問,結(jié)果:

          感覺這個(gè)防火墻有點(diǎn)叼。

          算了,使用大殺器來隱藏模擬瀏覽器的特征:

          from?selenium.webdriver?import?ChromeOptions
          from?selenium?import?webdriver
          browser?=?webdriver.Chrome()

          option?=?ChromeOptions()
          option.add_experimental_option('excludeSwitches',?['enable-automation'])
          option.add_experimental_option('useAutomationExtension',?False)
          option.add_argument(
          ????'user-agent=Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_15_7)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/86.0.4240.198?Safari/537.36')
          option.add_argument("--disable-blink-features=AutomationControlled")
          browser?=?webdriver.Chrome(options=option)

          with?open('stealth.min.js')?as?f:
          ????js?=?f.read()
          browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',?{
          ????'source':?js
          })
          url?=?'http://hotels.huazhu.com/inthotel/detail/9005308'
          browser.get(url)

          這回頁面總算是出來了:

          然而價(jià)格有時(shí)并不顯示,只能多刷新幾下頁面:

          多次訪問之后,數(shù)據(jù)總算能看到了。

          下面讓模擬器模擬點(diǎn)擊查看全部價(jià)格:

          from?selenium.webdriver.common.by?import?By
          from?selenium.webdriver.support.ui?import?WebDriverWait
          from?selenium.webdriver.support?import?expected_conditions?as?EC

          wait?=?WebDriverWait(browser,?10)

          table?=?wait.until(EC.element_to_be_clickable(
          ????(By.CSS_SELECTOR,?'#Pdetail_part2?table')))
          table.location_once_scrolled_into_view
          {'x':?0,?'y':?0}
          more_click?=?wait.until(EC.element_to_be_clickable(
          ????(By.CSS_SELECTOR,?'#Pdetail_part2?a[class="viewallprice"]')))
          more_click.click()

          這樣7條價(jià)格數(shù)據(jù),我們就全部能夠看到了。

          下面我們開始抓取我們需要的數(shù)據(jù):

          截圖獲取需要的數(shù)據(jù)

          from?io?import?BytesIO
          import?base64
          from?PIL?import?Image

          for?tr?in?table.find_elements_by_css_selector("table?tr[class^='room?first']"):
          ????print(tr.find_element_by_tag_name("h3").text)
          ????price?=?tr.find_element_by_css_selector(
          ????????"div>a[class^='totalprice']")
          ????img_data?=?base64.b64decode(price.screenshot_as_base64)
          ????img?=?Image.open(BytesIO(img_data))
          ????display(img)

          調(diào)整鼠標(biāo)滑動(dòng)的位置后再來一次:

          說明截圖有時(shí)截的并不準(zhǔn)確,想要精準(zhǔn)截圖也非常困難,因?yàn)闊o法通過程序準(zhǔn)確滾動(dòng)到應(yīng)該的位置。

          光截圖就能搞定,那就太簡單了。

          本文的主要目前還是為了演示解析CSS,咱們繼續(xù)采用解析法來獲取數(shù)據(jù):

          解析CSS獲取圖片數(shù)據(jù)

          首先我們解析出我們需要的數(shù)據(jù):

          img_url?=?None
          for?tr?in?table.find_elements_by_css_selector("table?tr[class^='room?first']"):
          ????name?=?tr.find_element_by_tag_name("h3").text
          ????print(name)
          ????price?=?tr.find_element_by_css_selector("div>a[class^='totalprice']")
          ????for?var?in?price.find_elements_by_tag_name("var"):
          ????????if?img_url?is?None:
          ????????????img_url?=?var.value_of_css_property("background-image")[5:-2]
          ????????????print(img_url)
          ????????position?=?var.value_of_css_property("background-position")
          ????????w,?h?=?map(lambda?x:?int(x[1:-2]),?position.split())
          ????????print(w,?h)
          高級(jí)大床房
          http://hotels.huazhu.com/Blur/Pic?b=81efc0b8e3094942a81d01e311864270
          170?2
          188?2
          126?2
          豪華大床房
          170?2
          33?2
          56?2
          豪華雙床房
          145?2
          2?2
          188?2
          觀景豪華大床房
          145?2
          170?2
          111?2
          行政大床房
          33?2
          56?2
          56?2
          行政雙床房
          201?2
          2?2
          145?2
          行政套房
          2?2
          2?2
          33?2
          188?2

          嘗試下載CSS背景圖片:

          browser.get(img_url)

          結(jié)果又是被騰訊T-Sec Web應(yīng)用防火墻(WAF)攔截的頁面,說明直接用selenium下載圖片行不通。

          用request下載呢?經(jīng)嘗試也老是被攔截。

          最終,寫出了如下代碼(還能較為順利的獲取圖片數(shù)據(jù)):

          import?requests
          from?io?import?BytesIO
          import?base64
          from?PIL?import?Image

          def?download_img(img_url):
          ????cookies?=?{o['name']:?o['value']?for?o?in?browser.get_cookies()}
          ????headers?=?{
          ????????"Accept":?"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
          ????????"Accept-Encoding":?"gzip,?deflate",
          ????????"Accept-Language":?"zh-CN,zh;q=0.9",
          ????????"Cache-Control":?"max-age=0",
          ????????"Connection":?"keep-alive",
          ????????"Host":?"hotels.huazhu.com",
          ????????"Upgrade-Insecure-Requests":?"1",
          ????????"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/86.0.4240.198?Safari/537.36"
          ????}

          ????for?_?in?range(10):
          ????????r?=?requests.get(img_url,?headers=headers,?cookies=cookies)
          ????????if?r.status_code?==?200:
          ????????????break
          ????else:
          ????????return?None
          ????img?=?Image.open(BytesIO(r.content))
          ????return?img
          img?=?download_img(img_url)
          img

          有了圖片,我們就可以裁剪出相應(yīng)的數(shù)字圖片并進(jìn)行拼接了。

          對(duì)最后一條數(shù)據(jù)進(jìn)行測試:

          可以看到解析和拼接的效果非常不錯(cuò)。

          然后測試批量的數(shù)據(jù)提?。?/p>

          img_url?=?None
          for?tr?in?table.find_elements_by_css_selector("table?tr[class^='room?first']"):
          ????name?=?tr.find_element_by_tag_name("h3").text
          ????print(name)
          ????price?=?tr.find_element_by_css_selector("div>a[class^='totalprice']")
          ????var_el_s?=?price.find_elements_by_tag_name("var")
          ????n?=?len(var_el_s)
          ????target?=?Image.new('RGB',?(10?*?n,?17),?color=(255,?255,?255))
          ????for?i,?var?in?enumerate(var_el_s):
          ????????if?img_url?is?None:
          ????????????img_url?=?var.value_of_css_property("background-image")[5:-2]
          ????????????img?=?download_img(img_url)
          ????????position?=?var.value_of_css_property("background-position")
          ????????w,?h?=?map(lambda?x:?int(x[1:-2]),?position.split())
          ????????r?=?img.crop((w,?h,?w+8,?h+17))
          ????????target.paste(r,?(10*i,?0),?r)
          ????display(target)

          可以看到已經(jīng)順利的得到了需要的結(jié)果,與網(wǎng)站看到的數(shù)據(jù)一致:

          剩下的我們僅僅只需要對(duì)拼接好的圖片進(jìn)行圖像識(shí)別即可,或者就直接原有圖片形式保存。

          圖像識(shí)別

          關(guān)于圖像識(shí)別,有在線識(shí)別和離線識(shí)別兩種方式。在線文字可以考慮使用百度云,騰訊云等,根據(jù)官網(wǎng)提供的接口進(jìn)行操作。

          下面呢,我們嘗試進(jìn)行離線文字識(shí)別,離線文字識(shí)別的準(zhǔn)確率往往不如在線。

          為了更好的識(shí)別效果,我們先對(duì)圖片進(jìn)行二值化處理:

          def?image_binarization(im,?threshold=250):
          ????Lim?=?im.convert("L")
          ????table?=?[0?if?i?else?1?for?i?in?range(256)]
          ????return?Lim.point(table,?"1")

          image_binarization(target)

          下面我們需要安裝pytesseract和Tesseract-OCR。

          pytesseract是一個(gè)Python庫:

          pip?insatll?pytesseract

          Tesseract-OCR則需要在https://digi.bib.uni-mannheim.de/tesseract/下載安裝包。

          由于網(wǎng)絡(luò)原因,我在https://www.liangchan.net/liangchan/11545.html下載了一個(gè)。

          項(xiàng)目地址:https://github.com/tesseract-ocr/tesseract

          安裝完成后,添加安裝路徑到path環(huán)境變量,命令行執(zhí)行后出現(xiàn)如下提示說明安裝成功:

          C:\Users\ASUS>tesseract?-v
          tesseract?v5.0.0.20190623
          ?leptonica-1.78.0
          ??libgif?5.1.4?:?libjpeg?8d?(libjpeg-turbo?1.5.3)?:?libpng?1.6.34?:?libtiff?4.0.9?:?zlib?1.2.11?:?libwebp?0.6.1?:?libopenjp2?2.3.0
          ?Found?AVX2
          ?Found?AVX
          ?Found?SSE

          C:\Users\ASUS>

          然后我們開始識(shí)別:

          import?pytesseract

          text?=?pytesseract.image_to_string(image_binarization(target)).strip()
          print(text)
          1183

          于是可以開始進(jìn)行批量識(shí)別了:

          import?pytesseract

          for?tr?in?table.find_elements_by_css_selector("table?tr[class^='room?first']"):
          ????name?=?tr.find_element_by_tag_name("h3").text
          ????price?=?tr.find_element_by_css_selector("div>a[class^='totalprice']")
          ????var_el_s?=?price.find_elements_by_tag_name("var")
          ????n?=?len(var_el_s)
          ????target?=?Image.new('RGB',?(10?*?n,?17),?color=(255,?255,?255))
          ????for?i,?var?in?enumerate(var_el_s):
          ????????if?img_url?is?None:
          ????????????img_url?=?var.value_of_css_property("background-image")[5:-2]
          ????????????img?=?download_img(img_url)
          ????????position?=?var.value_of_css_property("background-position")
          ????????w,?h?=?map(lambda?x:?int(x[1:-2]),?position.split())
          ????????r?=?img.crop((w,?h,?w+8,?h+17))
          ????????target.paste(r,?(10*i,?0),?r)
          ????display(target)
          ????text?=?pytesseract.image_to_string(image_binarization(target)).strip()
          ????print(name,?text)

          從結(jié)果可以看到,識(shí)別的準(zhǔn)確率還是非常高的,至少目前看到的全部都正確了。?

          版權(quán)聲明:本文為CSDN博主「小小明-代碼實(shí)體」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/as604049322/article/details/118401598

          ????小伙伴們,快快用實(shí)踐一下吧!如果在學(xué)習(xí)過程中,有遇到任何問題,歡迎加我好友,我拉你進(jìn)Python學(xué)習(xí)交流群共同探討學(xué)習(xí)。

          -------------------?End?-------------------

          往期精彩文章推薦:


          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入Python學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群

          萬水千山總是情,點(diǎn)個(gè)【在看】行不行


          /今日留言主題/

          隨便說一兩句吧~~

          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费大片黄在线播放 | 黄视频网站在线观看 | 俺也去com | 91人妻精 | 国产大鸡吧在线观看 |