CSDN使用了spring的webflow
<input type="hidden" name="lt" value="LT-58187-6D0O7tpTNBVqzLTbyULoyeLt9fMZd1" />
這個隱藏參數可以理解成每個需要登錄的用戶都有一個流水號。只有有了webflow發放的有效的流水號,用戶才可以說明是已經進入了webflow流程。否則,沒有流水號的情況下,webflow會認為用戶還沒有進入webflow流程,從而會重新進入一次webflow流程,從而會重新出現登錄界面。
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
#### 控制臺輸入賬號密碼相關, 如有特殊密碼保護,應使用getpass(需要注意的是Pycharm對此支持的不好)
import getpass
# Python 2 需要這么引入
# import urllib.quote
class CSDN(object):
"""
CSDN模擬登陸并加上點贊,評論,私信等功能。
"""
def __init__(self, headers):
"""
:param session: 創建全局的session對象,保證會話的一致性,有效性。
:param headers: 防止服務器端反爬蟲,添加偽裝頭部信息
"""
self.session = requests.Session()
self.headers = headers
def login(self, account, passwd):
"""
模擬登陸,點贊, 發評論,發私信的前提都是已在登錄狀態下進行的,這是前提。
:param account: 用戶名
:param passwd: 密碼
:return:
"""
self.username = account
self.password = passwd
# 只有獲取到webflow流水號,才會正式進入登陸通道,服務器端對此進行了限制。
lt, execution = self.get_webflow()
# 要提交的表單數據
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網頁就可以得到這串數據。應為是動態變化的
所以,先獲取下來,以備使用。
: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
先轉化一下為: 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:被點贊數:{}, 被踩數:{}'.format(articleurl, digg, bury))
else:
print('網絡或服務器出現了問題,點贊操作出現了點故障!')
self.headers['Referer'] = ''
def comment(self, articleurl, content):
"""
給定一個文章的路徑http://blog.csdn.net/marksinoberg/article/details/69569353,
需要轉化為形如: 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('服務器訪問成功,但評論操作失敗了!')
else:
print('評論出現了點異常!')
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("私信內容發送成功!")
# print(response.text)
## 這里服務器返回的是一大串HTML代碼。通過解析還可以得到本人和其他博友的私信記錄。
else:
print('私信發送失敗!請檢查網絡是否通暢。')
def publish_article(self):
"""
核心URL: http://write.blog.csdn.net/postedit?edit=1&isPub=1&joinblogcontest=undefined&r=0.14573376474383326
有興趣的可以嘗試著做一下。
需要提交的表單信息為:
titl:1234567 # 博客標題
typ:1 # 原創1, 轉載2, 翻譯3
cont:自動發現一篇好文章的前提是什么? # 發表的文章內容
desc:自動發現一篇好文章的前提是什么? # 發表的摘要信息
tags: # 標簽們
flnm:69803183 # 博客ID(如果是新文章默認沒有的)
chnl:0 # 文章類型: 編程語言啊, 系統架構啊什么的
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='僚機呼叫主機,收到請回復,Over!')