代码内的注释应该很明白了,额外说几点。第一点是由于__VIEWSTATE和__VIEWSSTATEGENERATOR字段是博客园生成的,所以我首先是用get请求,使用BeautifulSoup解析返回页面并找到__VIEWSTATE和__VIEWSSTATEGENERATOR,然后再构建data进行post提交。第二个点是由于先前我们已经注意到,返回的是一个302重定向页面,而requests是默认自动帮我们做重定向的,由于我们在后续的步骤中需要最原始的响应来帮助我们作判断,所以我们使用allow_redirects=False禁用了重定向。最后一点是post_article方法还支持以键值对的方式传递任意参数,这些参数最终会更新到data并提交至博客园,所以我们可以在调用方法时控制提交文章的一些选项,比如post_article(session,title,summary,content,Editor$Edit$Advanced$txbTag="Python")。
四、 获取判断返回结果
实际上,一般情况下调用post_article方法的后你的文章已经发布出去了,如果你想判断是否真的成功了,那么我们可以继续。
在第一部分我们知道了如果发布文章成功,那么服务器首先返回的是一个状态码为302的重定向页面,如果发布失败了,比如当我发表标题重复的文章又或者触碰了其他博客园规则,这时候服务器返回的就是一个状态码为200的普通页面。所以我们可以根据返回对象的status或者Localtion来做一层判断
1
2
3
|
location = response.headers.get( 'Location' ) if location: return True |
五、其他
值得一提的是,博客园文章的内容是基于html语言的,如果直接把普通文本提交到博客园,那么文章的排版肯定会十分混乱,所以对文章内容需要进行特别处理,由于我在写的博客系统,存储的文章内容本身就是基于html语言的,所以我这也就没有处理需求,在本文就不展开讲了。
新建文章也不仅仅只有我列出的那一部分字段,如果我没有列出来的,可以在form表单下的input标签。
五、完整示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#!/usr/bin/env python # -*- coding:utf-8 -*- from bs4 import BeautifulSoup import requests def get_login_session(cookie): headers = { 'referer' : 'https://i.cnblogs.com/' , 'cookie' : cookie } session = requests.session() session.headers.update(headers) return session def post_article(session,title,summary,content, * * kwargs): ''' 向博客园提交新文章 :param session:登录的session :param title: 文章标题 :param summary: 文章摘要 :param content: 文章内容 :param kwargs: 自定义form表单内容 :return: Response ''' url = 'https://i.cnblogs.com/EditPosts.aspx?opt=1' wb_data = session.get(url,allow_redirects = False ) soup = BeautifulSoup(wb_data.text, 'lxml' ) __VIEWSTATE = soup.find( id = '__VIEWSTATE' )[ 'value' ] __VIEWSTATEGENERATOR = soup.find( id = '__VIEWSTATEGENERATOR' )[ 'value' ] data = { 'Editor$Edit$lkbPost' : '', 'Editor$Edit$Advanced$ckbPublished' : 'on' , 'Editor$Edit$Advanced$chkDisplayHomePage' : 'on' , 'Editor$Edit$Advanced$chkComments' : 'on' , 'Editor$Edit$Advanced$chkMainSyndication' : 'on' , 'Editor$Edit$Advanced$txbEntryName' : '', 'Editor$Edit$Advanced$txbExcerpt' : summary, 'Editor$Edit$Advanced$txbTag' : '', 'Editor$Edit$Advanced$tbEnryPassword' : '', '__VIEWSTATE' : __VIEWSTATE, '__VIEWSTATEGENERATOR' : __VIEWSTATEGENERATOR, 'Editor$Edit$txbTitle' : title, 'Editor$Edit$EditorBody' : content} data.update(kwargs) response = session.post(url,data = data,allow_redirects = False ) return response if __name__ = = "__main__" : cookie = input ( '请输入博客园Cookie: ' ) session = get_login_session(cookie) response = post_article(session, '测试标题' , '测试摘要' , '测试内容' ) location = r.headers.get( 'Location' ) if location: print ( '文章发布成功' ) else : soup = BeautifulSoup(r.text, 'lxml' ) ErrorPanel = soup.find( 'div' , { 'class' : 'ErrorPanel' }) if ErrorPanel: print (ErrorPanel.get_text()) print ( '文章发布失败' ) |