CSDN使用了spring的webflow
<input type="hidden" name="lt" value="LT-58187-6D0O7tpTNBVqzLTbyULoyeLt9fMZd1" />
這個隱藏參數(shù)可以理解成每個需要登錄的用戶都有一個流水號。只有有了webflow發(fā)放的有效的流水號慷蠕,用戶才可以說明是已經(jīng)進入了webflow流程珊拼。否則,沒有流水號的情況下流炕,webflow會認為用戶還沒有進入webflow流程澎现,從而會重新進入一次webflow流程仅胞,從而會重新出現(xiàn)登錄界面。
import requests
from bs4 import BeautifulSoup
#######################################################
# Replace special characters in string using the %xx escape. Letters, digits,
# and the characters '_.-' are never quoted.
# Python 3 可以這么引入
from urllib.parse import quote
#### 控制臺輸入賬號密碼相關(guān), 如有特殊密碼保護剑辫,應(yīng)使用getpass(需要注意的是Pycharm對此支持的不好)
import getpass
# Python 2 需要這么引入
# import urllib.quote
class CSDN(object):
"""
CSDN模擬登陸并加上點贊干旧,評論,私信等功能妹蔽。
"""
def __init__(self, headers):
"""
:param session: 創(chuàng)建全局的session對象椎眯,保證會話的一致性,有效性胳岂。
:param headers: 防止服務(wù)器端反爬蟲编整,添加偽裝頭部信息
"""
self.session = requests.Session()
self.headers = headers
def login(self, account, passwd):
"""
模擬登陸,點贊乳丰, 發(fā)評論娄徊,發(fā)私信的前提都是已在登錄狀態(tài)下進行的恢总,這是前提。
:param account: 用戶名
:param passwd: 密碼
:return:
"""
self.username = account
self.password = passwd
# 只有獲取到webflow流水號,才會正式進入登陸通道阅嘶,服務(wù)器端對此進行了限制。
lt, execution = self.get_webflow()
# 要提交的表單數(shù)據(jù)
postdata = {
'username': account,
'password': passwd,
"lt": lt,
"execution": execution,
"_eventId": "submit"
}
## 開始登陸
loginurl = 'https://passport.csdn.net/account/login'
response = self.session.post(url=loginurl, headers=self.headers, data=postdata)
if response.status_code == 200:
print('恭喜您登陸成功师崎!')
else:
print(response.text)
print('登錄失敗瓜浸,請重試!')
def get_webflow(self):
"""
流水號webflow獲取秋冰。隨便訪問包含登陸頁鏈接的CSDN網(wǎng)頁就可以得到這串數(shù)據(jù)仲义。應(yīng)為是動態(tài)變化的
所以,先獲取下來剑勾,以備使用埃撵。
:return:
"""
url = 'https://passport.csdn.net/account/login?ref=toolbar'
response = self.session.get(url=url, headers=self.headers)
soup = BeautifulSoup(response.text, 'html.parser')
lt = soup.find('input', {'name': 'lt'})['value']
execution = soup.find('input', {'name': 'execution'})['value']
# 釋放不必要的對象
soup.clear()
return (lt, execution)
def digg(self, articleurl, digg=True):
"""
把給定的文章路徑 http://blog.csdn.net/marksinoberg/article/details/69569353
先轉(zhuǎn)化一下為: http://blog.csdn.net/marksinoberg/article/digg?ArticleId=69569353
:param articleurl 待操作的文章路徑
:param digg: 給文章點贊還是踩一下
:return:
"""
try:
bloguser, blogid = articleurl.split('/')[3], articleurl.split('/')[-1]
if digg==True:
diggurl = 'http://blog.csdn.net/{}/article/digg?ArticleId={}'.format(bloguser, blogid)
else:
diggurl = 'http://blog.csdn.net/{}/article/bury?ArticleId={}'.format(bloguser, blogid)
except:
print('您輸入的文章路徑非法!')
print("待操作文章的路徑: ", diggurl)
self.headers['X-Requested-With'] = 'XMLHttpRequest'
self.headers['Host'] = 'blog.csdn.net'
self.headers['Referer'] = articleurl
response = self.session.get(url=diggurl, headers=self.headers)
if response.status_code == 200:
# print("Digg 操作成功", response.text)
articlejson = response.json()
digg, bury = articlejson['digg'], articlejson['bury']
print('文章:{}\n:被點贊數(shù):{}, 被踩數(shù):{}'.format(articleurl, digg, bury))
else:
print('網(wǎng)絡(luò)或服務(wù)器出現(xiàn)了問題虽另,點贊操作出現(xiàn)了點故障暂刘!')
self.headers['Referer'] = ''
def comment(self, articleurl, content):
"""
給定一個文章的路徑http://blog.csdn.net/marksinoberg/article/details/69569353,
需要轉(zhuǎn)化為形如: http://blog.csdn.net/Marksinoberg/comment/submit?id=69569353
:param articleurl:
:param content:
:return:
"""
try:
bloguser, blogid = articleurl.split('/')[3], articleurl.split('/')[-1]
commenturl = 'http://blog.csdn.net/{}/comment/submit?id={}'.format(bloguser, blogid)
except:
print(commenturl, ' 不是一個合法的路徑捂刺!')
print(commenturl)
postdata = {
'commentid': self.username,
'replyid': bloguser,
'content': content
}
response = self.session.post(url=commenturl, headers=self.headers, data=postdata)
if response.status_code == 200:
print(response.json())
if response.json()['result'] == 1:
print('評論成功咯谣拣!')
else:
print('服務(wù)器訪問成功,但評論操作失敗了族展!')
else:
print('評論出現(xiàn)了點異常森缠!')
def letter(self, receiver, content):
letterurl = 'http://msg.csdn.net/letters/send_message?receiver={0}&body={1}'.format(receiver, quote(content))
response = self.session.get(url=letterurl, headers=self.headers)
if response.status_code == 200:
print("私信內(nèi)容發(fā)送成功!")
# print(response.text)
## 這里服務(wù)器返回的是一大串HTML代碼仪缸。通過解析還可以得到本人和其他博友的私信記錄贵涵。
else:
print('私信發(fā)送失敗!請檢查網(wǎng)絡(luò)是否通暢宾茂。')
def publish_article(self):
"""
核心URL: http://write.blog.csdn.net/postedit?edit=1&isPub=1&joinblogcontest=undefined&r=0.14573376474383326
有興趣的可以嘗試著做一下瓷马。
需要提交的表單信息為:
titl:1234567 # 博客標題
typ:1 # 原創(chuàng)1, 轉(zhuǎn)載2跨晴, 翻譯3
cont:自動發(fā)現(xiàn)一篇好文章的前提是什么决采? # 發(fā)表的文章內(nèi)容
desc:自動發(fā)現(xiàn)一篇好文章的前提是什么? # 發(fā)表的摘要信息
tags: # 標簽們
flnm:69803183 # 博客ID(如果是新文章默認沒有的)
chnl:0 # 文章類型: 編程語言啊坟奥, 系統(tǒng)架構(gòu)啊什么的
comm:2
level:0
tag2:
artid:0
checkcode:undefined
userinfo1:713
stat:publish
:return:
"""
if __name__ == '__main__':
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36",
}
csdn = CSDN(headers=headers)
account = input('請輸入您的賬號:')
password = getpass.getpass(prompt='請輸入您的密碼:')
csdn.login(account=account, passwd=password)
# 評論測試
# csdn.comment('http://blog.csdn.net/marksinoberg/article/details/69569353', '哈哈树瞭,爬蟲評論')
# 點贊,踩測試爱谁。digg為True為頂晒喷, 為False即踩
# csdn.digg('http://blog.csdn.net/marksinoberg/article/details/69569353', digg=True)
# 私信測試
# csdn.letter(receiver='marksinoberg', content='僚機呼叫主機,收到請回復(fù)访敌,Over凉敲!')