Python 豆瓣頂帖

🆙🆙

因爲在豆瓣發了個租房帖子,發現很快就被其餘的帖子淹沒,可是手動頂帖實在太累,😭,因此想經過自動頂帖的方式來解放雙手!php

評論請求分析

經過Chrome network 分析html

add_comment

  • 評論url是https://www.douban.com/group/topic/129122199/add_comment
  • 須要帶5個參數,其中 ck 是 cookie 裏面的值,rv_comment 是 評論
  • 返回302表明重定向

Python 模擬請求:python

# 豆瓣具體帖子
url = "https://www.douban.com/group/topic/129122199/"
# 豆瓣具體帖子回覆的接口,格式是帖子連接+/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': '發送'
}
response = requests.post(comment_url, headers=headers, allow_redirects=False,
                         data=params, verify=False)
複製代碼

直接運行便可。json

可是多運行幾回就會發現,返回的狀態碼是200,並且沒有頂帖成功。其實是觸發了豆瓣的防爬蟲。數組

觸發了豆瓣驗證碼

並且在咱們頂帖的時候發送請求的時候還帶有 captcha-solution 和 captcha-id 字段。bash

目前發現,每次評論就算相隔1分鐘,只要滿3次,就必定會彈出這個驗證碼進行驗證。微信

驗證碼解析

遇到驗證碼咱們就來破解驗證碼。cookie

tesserocr

識別圖形驗證碼須要安裝tesserocr這個庫,下面介紹下tesserocr。dom

tesserocr是Python的一個OCR識別庫,但實際上是對tesseract作了一層Python Api的封裝,核心仍是tesseract,因此在安裝tesserocr以前,須要先安裝tesseract。Tesseract(/‘tesərækt/) 這個詞的意思是」超立方體」,指的是幾何學裏的四維標準方體,又稱」正八胞體」,是一款被普遍使用的開源 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對象
    image = Image.open("/Users/liwenhao/Desktop/douban-captcha-example1.jpeg")
    # 調用tesserocr的image_to_text()方法,傳入image對象完成識別
    result = tesserocr.image_to_text(image)
    print(result)
複製代碼

驗證的圖片以下:

douban-captcha-example1
douban-captcha-example1

結果沒法識別。

換一張簡單的圖片試試:

captcha-example1.jpg

結果以下:

5594
複製代碼

看來 Tesseract 只能識別一些簡單的驗證碼,不適合豆瓣驗證碼識別。

試試識別驗證碼平臺。

百度OCR

官方接入文檔: 文字識別-Python SDK接入文檔

  • 重點:免費
  • 通用識別(包括身份證、銀行卡)500次/日,
  • 高精度則50次/日,
  • 駕駛證,行駛證,車票,營業執照,通用票據均爲200次/日

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

配置流程:

  1. 先開通個百度的帳號;

  2. 開通文字識別服務,打開後點擊當即使用:cloud.baidu.com/product/ocr…

  3. 點擊步驟2,應該有個信息確認的,確認後,會進入到用戶我的首頁,向下滑動,直接點擊文字識別:

  4. 點擊建立應用,輸入一堆內容後,點擊確認便可,而後點擊個人應用,這裏面的API KeySecret Key須要使用到:

  5. 點擊右上角,用戶中心,用戶ID也須要用到:

  6. 須要的信息準備好了,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')
    """ 調用通用文字識別(高精度), 圖片參數爲本地圖片 """
    result = json.dumps(client.basicAccurate(image))
    print(result)
複製代碼

驗證的圖片以下:

douban-captcha-example1
douban-captcha-example1

結果走一波:

{"log_id": 3968431492157876638, "words_result_num": 1, "words_result": [{"words": " minute:"}]}
複製代碼

從結果能夠看出識別出了這個驗證碼。

  • words_result_num 是識別結果數
  • words_result 是定位和識別結果數組
  • words 是識別結果字符串

再來試試

douban-captcha-example2
douban-captcha-example2

結果以下:

{"log_id": 5251449865676063710, "words_result_num": 0, "words_result": []}
複製代碼

沒有識別出來,能夠看到對於複雜一些的驗證碼仍是會出現沒法識別的狀況,可是勝在免費。

超級鷹

對於沒法識別的狀況就須要打碼平臺了,業界比較出名的是 超級鷹

超級鷹是按量級收費,量大便宜,標準價格:1元=1000題分,不一樣驗證碼類型,須要的題分不同,詳情能夠到這裏查詢 www.chaojiying.com/price.html

python 代碼以下:

from hashlib import md5
import requests
import json


# 經過超級鷹識別驗證碼
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()
    return resp


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

上傳的驗證碼就是上面百度 OCR 不曾識別的驗證碼,以下:

douban-captcha-example2
douban-captcha-example2
結果以下:

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

發現 驗證碼 yacvmd 已出來。可是時間花了5s左右。後來測試發現對於豆瓣比較建的驗證碼花費的時間在1s內,所以從時間和準確性上面,最後仍是採用了超級鷹打碼平臺。

失敗微信通知

不管採用什麼方式,都有可能出現失敗的狀況,我總不能採起 輪詢 的方式,隔幾個小時就去看看到底前面幾回是否🆙成功,所以須要一個 異步通知 ,最開始想用 郵件,後來發現了 Server醬 這個神器,能夠幫助咱們發送微信通知,並且特別簡單。

具體能夠查看 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()


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


# 經過超級鷹識別驗證碼
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()
    # 錯誤處理
    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失敗,發送失敗信息到微信")


# 豆瓣頂帖
def douban_ding():
    # 豆瓣具體帖子
    url = "https://www.douban.com/group/topic/129122199/"
    # 豆瓣具體帖子回覆的接口,格式是帖子連接+/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': '發送'
    }
    response = requests.get(url, headers=headers, verify=False).content.decode('utf-8')
    selector = html.fromstring(response)
    captcha_image = selector.xpath("//img[@id=\"captcha_image\"]/@src")
    if captcha_image:
        logging.info("發現驗證碼,下載驗證碼")
        captcha_id = selector.xpath("//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("沒有驗證碼")
    response = requests.post(comment_url, headers=headers, allow_redirects=False,
                             data=params, verify=False)
    result_verification(response)


if __name__ == '__main__':
    douban_ding()
複製代碼

運行結果:

  1. 第1次:
    2018-12-30 16:09:35.589 INFO: 沒有驗證碼
    2018-12-30 16:09:36.436 INFO: 豆瓣ding成功
    複製代碼
  2. 第4次:
    2018-12-30 16:13:02.135 INFO: 發現驗證碼,下載驗證碼
    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成功
    複製代碼

效果圖:

注:

  1. 頂帖的時候控制好頻率,否則容易被禁言。
    豆瓣禁言
相關文章
相關標籤/搜索