Python 豆瓣頂帖

image

由于在豆瓣發(fā)了個(gè)租房帖子爷速,發(fā)現(xiàn)很快就被其他的帖子淹沒,但是手動(dòng)頂帖實(shí)在太累霞怀,??惫东,所以想通過自動(dòng)頂帖的方式來解放雙手!

評(píng)論請(qǐng)求分析

通過Chrome network 分析

image
  • 評(píng)論url是https://www.douban.com/group/topic/129122199/add_comment
  • 需要帶5個(gè)參數(shù)毙石,其中 ck 是 cookie 里面的值廉沮,rv_comment 是 評(píng)論
  • 返回302代表重定向

Python 模擬請(qǐng)求:

# 豆瓣具體帖子
url = "https://www.douban.com/group/topic/129122199/"
# 豆瓣具體帖子回復(fù)的接口,格式是帖子鏈接+/add_comment
comment_url = url + "/add_comment"
cookie = 'cookie'
referer = url
agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
headers = {
    "Host": "www.douban.com",
    "Referer": referer,
    'User-Agent': agent,
    "Cookie": cookie
}
params = {
    "rv_comment": '??',
    "ck": re.findall("ck=(.*?);", headers["Cookie"])[-1],
    'start': '0',
    'submit_btn': '發(fā)送'
}
response = requests.post(comment_url, headers=headers, allow_redirects=False,
                         data=params, verify=False)

直接運(yùn)行即可徐矩。

但是多運(yùn)行幾次就會(huì)發(fā)現(xiàn)滞时,返回的狀態(tài)碼是200,而且沒有頂帖成功滤灯。實(shí)際上是觸發(fā)了豆瓣的防爬蟲坪稽。

image

而且在我們頂帖的時(shí)候發(fā)送請(qǐng)求的時(shí)候還帶有 captcha-solution 和 captcha-id 字段。

image

目前發(fā)現(xiàn)鳞骤,每次評(píng)論就算相隔1分鐘窒百,只要滿3次,就一定會(huì)彈出這個(gè)驗(yàn)證碼進(jìn)行驗(yàn)證豫尽。

驗(yàn)證碼解析

遇到驗(yàn)證碼我們就來破解驗(yàn)證碼篙梢。

tesserocr

識(shí)別圖形驗(yàn)證碼需要安裝tesserocr這個(gè)庫,下面介紹下tesserocr美旧。

tesserocr是Python的一個(gè)OCR識(shí)別庫渤滞,但其實(shí)是對(duì)tesseract做了一層Python Api的封裝贬墩,核心還是tesseract,所以在安裝tesserocr之前蔼水,需要先安裝tesseract震糖。Tesseract(/‘tes?r?kt/) 這個(gè)詞的意思是”超立方體”,指的是幾何學(xué)里的四維標(biāo)準(zhǔn)方體趴腋,又稱”正八胞體”吊说,是一款被廣泛使用的開源 OCR 工具。

在Mac下优炬,使用 brew 安裝

brew install tesseract --all-languages

接下來再安裝tesserocr即可:

brew install imagemagick
pip install tesserocr pillow

Python 代碼如下:

import tesserocr

from PIL import Image

if __name__ == '__main__':
    # 新建Image對(duì)象
    image = Image.open("/Users/liwenhao/Desktop/douban-captcha-example1.jpeg")
    # 調(diào)用tesserocr的image_to_text()方法颁井,傳入image對(duì)象完成識(shí)別
    result = tesserocr.image_to_text(image)
    print(result)

驗(yàn)證的圖片如下:

douban-captcha-example1

結(jié)果無法識(shí)別。

換一張簡單的圖片試試:


captcha-example1.jpg

結(jié)果如下:

5594

看來 Tesseract 只能識(shí)別一些簡單的驗(yàn)證碼蠢护,不適合豆瓣驗(yàn)證碼識(shí)別雅宾。

試試識(shí)別驗(yàn)證碼平臺(tái)。

百度OCR

官方接入文檔: 文字識(shí)別-Python SDK接入文檔

  • 重點(diǎn):免費(fèi)
  • 通用識(shí)別(包括身份證葵硕、銀行卡)500次/日眉抬,
  • 高精度則50次/日,
  • 駕駛證懈凹,行駛證蜀变,車票,營業(yè)執(zhí)照介评,通用票據(jù)均為200次/日

注意:
支持2.7.+及3.+

配置流程:

  1. 先開通個(gè)百度的賬號(hào)库北;

  2. 開通文字識(shí)別服務(wù),打開后點(diǎn)擊立即使用:https://cloud.baidu.com/product/ocr.html

  3. 點(diǎn)擊步驟2们陆,應(yīng)該有個(gè)信息確認(rèn)的寒瓦,確認(rèn)后,會(huì)進(jìn)入到用戶個(gè)人首頁坪仇,向下滑動(dòng)杂腰,直接點(diǎn)擊文字識(shí)別:


    x
  4. 點(diǎn)擊創(chuàng)建應(yīng)用,輸入一堆內(nèi)容后椅文,點(diǎn)擊確認(rèn)即可颈墅,然后點(diǎn)擊我的應(yīng)用,這里面的API KeySecret Key需要使用到:

    image

  5. 點(diǎn)擊右上角雾袱,用戶中心,用戶ID也需要用到:


    image
  6. 需要的信息準(zhǔn)備好了官还,pip 安裝一波

    pip install baidu-aip
    

測試一波

import json

from aip import AipOcr

if __name__ == '__main__':
    APP_ID = ' '
    API_KEY = ' '
    SECRET_KEY = ' '

    client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

    # 讀取圖片
    def get_file_content(file_path):
        with open(file_path, 'rb') as fp:
            return fp.read()


    image = get_file_content('/Users/liwenhao/Desktop/douban-captcha-example2.jpg')
    """ 調(diào)用通用文字識(shí)別(高精度), 圖片參數(shù)為本地圖片 """
    result = json.dumps(client.basicAccurate(image))
    print(result)

驗(yàn)證的圖片如下:

douban-captcha-example1

結(jié)果走一波:

{"log_id": 3968431492157876638, "words_result_num": 1, "words_result": [{"words": " minute:"}]}

從結(jié)果可以看出識(shí)別出了這個(gè)驗(yàn)證碼芹橡。

  • words_result_num 是識(shí)別結(jié)果數(shù)
  • words_result 是定位和識(shí)別結(jié)果數(shù)組
  • words 是識(shí)別結(jié)果字符串

再來試試

douban-captcha-example2

結(jié)果如下:

{"log_id": 5251449865676063710, "words_result_num": 0, "words_result": []}

沒有識(shí)別出來,可以看到對(duì)于復(fù)雜一些的驗(yàn)證碼還是會(huì)出現(xiàn)無法識(shí)別的情況望伦,但是勝在免費(fèi)林说。

超級(jí)鷹

對(duì)于無法識(shí)別的情況就需要打碼平臺(tái)了煎殷,業(yè)界比較出名的是 超級(jí)鷹

超級(jí)鷹是按量級(jí)收費(fèi)腿箩,量大便宜豪直,標(biāo)準(zhǔn)價(jià)格:1元=1000題分,不同驗(yàn)證碼類型珠移,需要的題分不一樣弓乙,詳情可以到這里查詢 http://www.chaojiying.com/price.html

python 代碼如下:

from hashlib import md5
import requests
import json


# 通過超級(jí)鷹識(shí)別驗(yàn)證碼
def recognition_captcha(filename, code_type):
    im = open(filename, 'rb').read()
    params = {
        'user': '賬號(hào)',
        'pass2': md5('密碼'.encode('utf8')).hexdigest(),
        'softid': 'softid',
        'codetype': code_type
    }
    headers = {
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
    }
    files = {'userfile': ('ccc.jpg', im)}
    resp = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                         headers=headers).json()
    return resp


# 調(diào)用代碼
if __name__ == '__main__':
    print(json.dumps(recognition_captcha('/Users/liwenhao/Desktop/douban-captcha-example2.jpg', 1006)))

上傳的驗(yàn)證碼就是上面百度 OCR 未曾識(shí)別的驗(yàn)證碼,如下:

douban-captcha-example2

結(jié)果如下:

{"err_str": "OK", "err_no": 0, "md5": "0475b05654c376deb409bfef7eee75cd", "pic_id": "8054415552001300054", "pic_str": "yacvmd"}

發(fā)現(xiàn) 驗(yàn)證碼 yacvmd 已出來钧惧。但是時(shí)間花了5s左右暇韧。后來測試發(fā)現(xiàn)對(duì)于豆瓣比較建的驗(yàn)證碼花費(fèi)的時(shí)間在1s內(nèi),因此從時(shí)間和準(zhǔn)確性上面浓瞪,最后還是采用了超級(jí)鷹打碼平臺(tái)懈玻。

失敗微信通知

無論采用什么方式,都有可能出現(xiàn)失敗的情況乾颁,我總不能采取 輪詢 的方式涂乌,隔幾個(gè)小時(shí)就去看看到底前面幾次是否??成功,因此需要一個(gè) 異步通知 英岭,最開始想用 郵件湾盒,后來發(fā)現(xiàn)了 Server醬 這個(gè)神器,可以幫助我們發(fā)送微信通知巴席,而且特別簡單历涝。

具體可以查看 Server醬

完整代碼

采用 python2

import os

import requests
import urllib3
import re
from hashlib import md5
import random
from lxml import html
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S')
urllib3.disable_warnings()


# 下載驗(yàn)證碼圖片
def download_captcha(captcha_url, agent):
    # findall返回的是一個(gè)列表
    captcha_name = re.findall("id=(.*?):", captcha_url)
    filename = "douban_%s.jpg" % (str(captcha_name[0]))
    logging.info("文件名為: " + filename)
    with open(filename, 'wb') as f:
        # 以二進(jìn)制寫入的模式在本地構(gòu)建新文件
        header = {
            'User-Agent': agent,
            'Referer': captcha_url
        }
        f.write(requests.get(captcha_url, headers=header).content)
        logging.info("%s 下載完成" % filename)
    return filename


# 通過超級(jí)鷹識(shí)別驗(yàn)證碼
def recognition_captcha(filename, code_type):
    im = open(filename, 'rb').read()
    params = {
        'user': '用戶',
        'pass2': md5('密碼'.encode('utf8')).hexdigest(),
        'softid': 'softid',
        'codetype': code_type
    }
    headers = {
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
    }
    files = {'userfile': ('ccc.jpg', im)}
    resp = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                         headers=headers).json()
    # 錯(cuò)誤處理
    if resp.get('err_no', 0) == 0:
        return resp.get('pic_str')


def result_verification(response):
    if response.status_code == 302:
        logging.info("豆瓣ding成功")
    else:
        logging.info(response.status_code)
        logging.info(response)
        url = "https://sc.ftqq.com/你的SCKEY.send?text=douban失敗" + \
              str(random.randint(0, 1000))
        requests.post(url)
        logging.info("豆瓣ding失敗漾唉,發(fā)送失敗信息到微信")


# 豆瓣頂帖
def douban_ding():
    # 豆瓣具體帖子
    url = "https://www.douban.com/group/topic/129122199/"
    # 豆瓣具體帖子回復(fù)的接口荧库,格式是帖子鏈接+/add_comment
    comment_url = url + "/add_comment"
    cookie = 'cookie'
    referer = url
    agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
    headers = {
        "Host": "www.douban.com",
        "Referer": referer,
        'User-Agent': agent,
        "Cookie": cookie
    }
    params = {
        "rv_comment": '??',
        "ck": re.findall("ck=(.*?);", headers["Cookie"])[-1],
        'start': '0',
        'submit_btn': '發(fā)送'
    }
    response = requests.get(url, headers=headers, verify=False).content.decode('utf-8')
    selector = html.fromstring(response)
    captcha_image = selector.xpath("http://img[@id=\"captcha_image\"]/@src")
    if captcha_image:
        logging.info("發(fā)現(xiàn)驗(yàn)證碼,下載驗(yàn)證碼")
        captcha_id = selector.xpath("http://input[@name=\"captcha-id\"]/@value")
        filename = download_captcha(captcha_image[0], agent)
        captcha_solution = recognition_captcha(filename, 1006)
        os.remove(filename)
        params['captcha-solution'] = captcha_solution
        params['captcha-id'] = captcha_id
    else:
        logging.info("沒有驗(yàn)證碼")
    response = requests.post(comment_url, headers=headers, allow_redirects=False,
                             data=params, verify=False)
    result_verification(response)


if __name__ == '__main__':
    douban_ding()

運(yùn)行結(jié)果:

  1. 第1次:
    2018-12-30 16:09:35.589 INFO: 沒有驗(yàn)證碼
    2018-12-30 16:09:36.436 INFO: 豆瓣ding成功
    
  2. 第4次:
    2018-12-30 16:13:02.135 INFO: 發(fā)現(xiàn)驗(yàn)證碼赵刑,下載驗(yàn)證碼
    2018-12-30 16:13:02.135 INFO: 文件名為: douban_OJGsVa0hST4O2WhFA0VpMnR9.jpg
    2018-12-30 16:13:02.554 INFO: douban_OJGsVa0hST4O2WhFA0VpMnR9.jpg 下載完成
    2018-12-30 16:13:09.687 INFO: 豆瓣ding成功
    

效果圖:

image

注:

  1. 頂帖的時(shí)候控制好頻率分衫,不然容易被禁言。
    image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末般此,一起剝皮案震驚了整個(gè)濱河市蚪战,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铐懊,老刑警劉巖邀桑,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異科乎,居然都是意外死亡壁畸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捏萍,“玉大人太抓,你說我怎么就攤上這事×铊荆” “怎么了走敌?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逗噩。 經(jīng)常有香客問我掉丽,道長,這世上最難降的妖魔是什么给赞? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任机打,我火速辦了婚禮,結(jié)果婚禮上片迅,老公的妹妹穿的比我還像新娘残邀。我一直安慰自己,他們只是感情好柑蛇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布芥挣。 她就那樣靜靜地躺著,像睡著了一般耻台。 火紅的嫁衣襯著肌膚如雪空免。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天盆耽,我揣著相機(jī)與錄音蹋砚,去河邊找鬼。 笑死摄杂,一個(gè)胖子當(dāng)著我的面吹牛坝咐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播析恢,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼墨坚,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了映挂?” 一聲冷哼從身側(cè)響起泽篮,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柑船,沒想到半個(gè)月后帽撑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鞍时,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年油狂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡专筷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒸苇,到底是詐尸還是另有隱情磷蛹,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布溪烤,位于F島的核電站味咳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏檬嘀。R本人自食惡果不足惜槽驶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸳兽。 院中可真熱鬧掂铐,春花似錦、人聲如沸揍异。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衷掷。三九已至辱姨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間戚嗅,已是汗流浹背雨涛。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懦胞,地道東北人替久。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像医瘫,于是被迫代替她去往敵國和親侣肄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在爬蟲過程中醇份,難免會(huì)遇到各種各樣的驗(yàn)證碼稼锅,而大多數(shù)驗(yàn)證碼還是圖形驗(yàn)證碼,這時(shí)候我們可以直接用OCR來識(shí)別僚纷。 1. ...
    Einbahn_2018閱讀 7,752評(píng)論 1 2
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    小邁克閱讀 2,961評(píng)論 1 3
  • 第一步安裝 Tesserocr的安裝爬蟲過程中難免會(huì)遇到各種各樣的驗(yàn)證碼矩距,而大多數(shù)驗(yàn)證碼還是圖形驗(yàn)證碼,這時(shí)候我們...
    何苦_python_java閱讀 8,458評(píng)論 0 1
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫怖竭、插件锥债、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評(píng)論 4 62
  • 我的能力真的配得上我做的事嗎?我究竟是為了別人的認(rèn)可還是自己內(nèi)心呢?我是想要當(dāng)網(wǎng)紅哮肚?為了新鮮感對(duì)錯(cuò)感登夫?看似好像收獲...
    全能lady云飛閱讀 159評(píng)論 0 0