• Stars
    star
    434
  • Rank 99,601 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

爬取知识星球,并制作成 PDF 电子书。

爬取知识星球,并制作成 PDF 电子书。

功能

爬取知识星球的精华区,并制作成 PDF 电子书。

效果图

效果图.png

用法

if __name__ == '__main__':
    start_url = 'https://api.zsxq.com/v1.10/groups/454584445828/topics?scope=digests&count=20'
    make_pdf(get_data(start_url))

把 start_url 改为你需要爬取的星球的相应 url 。

还有安装好 wkhtmltox ,参考后面的「制作 PDF 电子书」。

模拟登陆

爬取的是网页版知识星球,https://wx.zsxq.com/dweb/#

这个网站并不是依靠 cookie 来判断你是否登录,而是请求头中的 Authorization 字段。

所以,需要把 Authorization,User-Agent 换成你自己的。(注意 User-Agent 也要换成你自己的)

headers = {
    'Authorization': '3704A4EE-377E-1C88-B031-0A42D9E9Bxxx',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
}

分析页面

登录成功后,一般我习惯右键、检查或者查看源代码。

但是这个页面比较特殊,它不把内容放到当前地址栏 URL 下,而是通过异步加载(XHR),只要找对接口就可以了。

精华区的接口:https://api.zsxq.com/v1.10/groups/2421112121/topics?scope=digests&count=20

这个接口是最新 20 条数据的,还有后面数据对应不同接口,这就是后面要说的翻页。

image.png | left | 827x710

制作 PDF 电子书

  • 安装 wkhtmltox,https://wkhtmltopdf.org/downloads.html 。安装后将 bin 目录加入到环境变量。
  • 安装相应依赖:pip install pdfkit
  • 这个工具是把 HTML 文档转换为 PDF 格式。根据 HTML 文档中的 h 标签,也就是标题标签来自动提取出目录。
  • 本来精华区是没有标题的,我把每个问题的前 6 个字符当做标题,以此区分不同问题。

下面进阶完美操作:

爬取图片

很明显,在返回的数据中的 images 键就是图片,只需提取 large 的,即高清的 url 即可。

关键在于将图片标签 img 插入到 HTML 文档。

我使用 BeautifulSoup 操纵 DOM 的方式。

需要注意的是,有可能图片不止一张,所以需要用 for 循环全部迭代出来

if content.get('images'):
    soup = BeautifulSoup(html_template, 'html.parser')
    for img in content.get('images'):
        url = img.get('large').get('url')
        img_tag = soup.new_tag('img', src=url)
        soup.body.append(img_tag)
        html_img = str(soup)
        html = html_img.format(title=title, text=text)

翻页问题

  • https://api.zsxq.com/v1.10/groups/2421112121/topics?scope=digests&count=20&end_time=2018-04-12T15%3A49%3A13.443%2B0800

  • 路径后面的 end_time 表示加载帖子的最后日期,以此达到翻页。

  • 这个 end_time 是经过 url 转义了的,可以通过 urllib.parse.quote 方法进行转义,关键是找出这个 end_time 是从那里来的。

  • 经过我细细观察发现:每次请求返回 20 条帖子,最后一条贴子就与下一条链接的 end_time 有关系。

  • 例如最后一条帖子的 create_time 是 2018-01-10T11:49:39.668+0800,那么下一条链接的 end_time 就是 2018-01-10T11:49:39.667+0800,注意,一个 668,一个 667 , 两者相差 1。

end_time = create_time[:20]+str(int(create_time[20:23])-1)+create_time[23:]
  • 翻页到最后返回的数据是:
{"succeeded":true,"resp_data":{"topics":[]}}

故以 next_page = rsp.json().get('resp_data').get('topics') 来判断是否有下一页。

制作精美 PDF

通过 css 样式来控制字体大小、布局、颜色等,详见 test.css 文件。

再将此文件引入到 options 字段中。

    options = {
        "user-style-sheet": "test.css",
        ...
        }

最难搞的问题是:Old iron, give me a star ! ! !