[专题] Python-Tkinter 项目编程入门
继续之前的 Tkinter 界面交互的文章.
Options.py
我们需要把浏览器的 Cookies 以及各种 Headers 信息提供给 Python, 这样才能模拟自己的用户登录信息, 更多内容可以参考这个较早的文章 [网络数据抓取 - Python - 爬虫 - Header-Boss 直聘] .
为了不干扰 reqs.py 文件, 我们创建一个 modules/options.py 文件用来放置这些信息, 它的代码如下:
- savePath='../data'
- urlVolumns = 'https://www.jianshu.com/author/notebooks'
- params = {'order_by': 'shared_at', 'page': '1'}
- headers = '''
- accept: application/json
- ... 这些内容从浏览器的控制台中复制得到, 参见下面...
- user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) ApplewebKit/537.36 (Khtml, like Gecko) Chrome/74.0.3729.169 Safari/537.36
- '''def str2obj(s, s1=';', s2='='):
- li = s.split(s1)
- res = {}
- for kv in li:
- li2 = kv.split(s2)
- if len(li2)> 1:
- res[li2[0]] = li2[1]
- return res
- headers = str2obj(headers, '\n', ':')
这里的 headers 字段可以从 Chrome 浏览器的[控制台 - Networks] 对应的接口中复制得到, 如下图:
有两点特别需要注意:
冒号开头的不要复制, 比如: authority... 这样的不要.
要去掉
if-none-match: W/...
这行, 这个的意思是如果本地有缓存那么就不读取, 可能会得到 304 错误, 去掉后就可以强制读取了.
关于上面的 str2obj 函数, 这是将 header 的字符串格式转换为对象格式 {'accept':'application/json',...}, 你可以在这里添加 print(headers) 来测试观看结果.
获取文集数据
首先我们注释掉 getAll 中的内容, 这样我们就可以直接运行 reqs.py 文件而不必去用待界面的 main.py 测试.
我们在 modules/reqs.py 中直接引入刚才撰写的 options.py 文件, 并引入 JSON:
- import options as opt
- import JSON
然后我们就可以使用了, 先修改最底部获取文集的函数 getVolums:
- def getVolums(): # 获取文集列表
- res = requests.get(opt.urlVolumns, headers=opt.headers)
- resdata = JSON.loads(res.text)
- print(resdata)
- return 'getVolums OK!'
- getVolums()
运行后就会输出你的文集列表数据, 类似[{'id': 32873510, 'name': '人工智能 DBD', 'seq': 0}, {'id': 34298143,... 这样的数据, 每一个 id 对应一个文集.
获取文章列表
然后我们修改获取每个文章的函数 getArticlesList, 并在 getVolums 中调用它:
- def getArticlesList(volId): # 获取文章列表
- urlVol = 'https://www.jianshu.com/author/notebooks/'+str(volId)+'/notes'
- res = requests.get(urlVol, headers=opt.headers)
- resdata = JSON.loads(res.text)
- print(resdata)
- return 'getArticlesList OK!'
- def getVolums(): # 获取文集列表
- res = requests.get(opt.urlVolumns, headers=opt.headers)
- resdata = JSON.loads(res.text)
- for d in resdata[:1]:
- time.sleep(1)
- getArticlesList(d['id'])
- return 'getVolums OK!'
- getVolums()
在 getVolums 中我们向 getArticlesList 传递了文集的 id 即 getArticlesList(d['id']), 然后再 getArticlesList 中我们拼合了每一文集的地址 urlVol, 然后再获取.
注意这里我们只测试获取了第一个文集的文章列表. 所以打印出来的情况是[{'id': 44398213, 'slug': '1839738a0f3f', 'shared': True, 'notebook_id': 32873510, 'seq_in_nb': 0, 'note_type': 2, 'autosave_control': 26, 'title': '人工智能通识 DBD-2019 年 4 月汇总', 'content_updated_at': 1554554957,...
获取文章内容
和上面的方法类似, 我们进一步修改:
- def getArticle(artId): # 获取文章内容
- global afini
- urlArt = 'https://www.jianshu.com/author/notes/'+str(artId)+'/content'
- res = requests.get(urlArt, headers=opt.headers)
- resdata = JSON.loads(res.text)
- print(resdata)
- afini += 1
- return 'getArticles OK!'
- def getArticlesList(volId): # 获取文章列表
- urlVol = 'https://www.jianshu.com/author/notebooks/'+str(volId)+'/notes'
- res = requests.get(urlVol, headers=opt.headers)
- resdata = JSON.loads(res.text)
- for d in resdata[:1]:
- time.sleep(1)
- getArticle(d['id'])
- return 'getArticlesList OK!'
- def getVolums(): # 获取文集列表
- res = requests.get(opt.urlVolumns, headers=opt.headers)
- resdata = JSON.loads(res.text)
- for d in resdata[:1]:
- time.sleep(1)
- getArticlesList(d['id'])
- return 'getVolums OK!'
- getVolums()
这样运行起来的话就可以得到第一个文集的第一个文章的内容, 比如 {'content': '欢迎关注我的专栏( つ •̀ω•́) つ[[人工智能通识] ](https://www.jianshu.com/c/e9a7b7b7024d)\n\n---\n0404 [软件技术 - WebVR-AFrame 文字的实现](https://www.jianshu.com/p/ac92a4e0bf84)...
后续我们还要将这些文章的内容分别存储起来, 并且读取其中包含的图片文件.
来源: http://www.jianshu.com/p/3becbe38fcf4