由于在豆瓣發(fā)了個(gè)租房帖子爷速,發(fā)現(xiàn)很快就被其他的帖子淹沒,但是手動(dòng)頂帖實(shí)在太累霞怀,??惫东,所以想通過自動(dòng)頂帖的方式來解放雙手!
評(píng)論請(qǐng)求分析
通過Chrome network 分析
- 評(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ā)了豆瓣的防爬蟲坪稽。
而且在我們頂帖的時(shí)候發(fā)送請(qǐng)求的時(shí)候還帶有 captcha-solution 和 captcha-id 字段。
目前發(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)證的圖片如下:
結(jié)果無法識(shí)別。
換一張簡單的圖片試試:
結(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.+
配置流程:
先開通個(gè)百度的賬號(hào)库北;
開通文字識(shí)別服務(wù),打開后點(diǎn)擊立即使用:https://cloud.baidu.com/product/ocr.html
-
點(diǎn)擊步驟2们陆,應(yīng)該有個(gè)信息確認(rèn)的寒瓦,確認(rèn)后,會(huì)進(jìn)入到用戶個(gè)人首頁坪仇,向下滑動(dòng)杂腰,直接點(diǎn)擊文字識(shí)別:
-
點(diǎn)擊創(chuàng)建應(yīng)用,輸入一堆內(nèi)容后椅文,點(diǎn)擊確認(rèn)即可颈墅,然后點(diǎn)擊我的應(yīng)用,這里面的API Key 跟Secret Key需要使用到:
-
點(diǎn)擊右上角雾袱,用戶中心,用戶ID也需要用到:
-
需要的信息準(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)證的圖片如下:
結(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é)果字符串
再來試試
結(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)證碼,如下:
結(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次:
2018-12-30 16:09:35.589 INFO: 沒有驗(yàn)證碼 2018-12-30 16:09:36.436 INFO: 豆瓣ding成功
- 第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成功
效果圖:
注:
-
頂帖的時(shí)候控制好頻率分衫,不然容易被禁言。