美文网首页爬虫Python 运维Python_Study
爬取简书全站文章并生成 API(一)

爬取简书全站文章并生成 API(一)

作者: 田飞雨 | 来源:发表于2016-07-28 11:35 被阅读5958次
    简书

    简书中的优质文章非常多,而且我非常喜欢 Markdown 这种语法格式,所以想着能不能爬取简书上面的文章,爬取文章之前先带大家来了解下简书整个网站,简书的首页分为“热门(已推到首页的)“,“新上榜(编辑已通过,但还没上首页的文章,等待队列中)”,“日报”,“七日热门”和“三十日热门”,“有奖活动”,“简书出版”和“简书播客”。简书还有一种绕开等待队列上首页的方式,就是“今日看点”专题,这个是不能投稿,编辑快速把文章推到首页的方式。

    下面带大家爬取的是简书的 “热门” 和 “新上榜” 这两个目录里面的文章,“热门”每页有 20 篇文章,最多可以加载 15 页。“新上榜” 每页有 18 篇文章,可以加载的页数没有限制,理论可以爬取所有的文章。


    1. 网页源码分析:

    以下是简书首页文章处的源码:


    文章源码

    若文章没有被打赏过,则“打赏”在网页源码中不会存在,代码中会进行处理,剩下的都会存在,但在爬取“热门”目录下的文章时,“阅读数”,“评论数”,“喜欢” 也会出问题,所以代码中也都做了相应的处理。


    data-url

    data-url 对应下一页的 URL

    简书各个目录代码格式相同,所以相同的方法也可以爬取简书其余几个分类目录。

    2. 爬取简书热门文章

    此爬虫使用 pythonBeautifulSoup 模块进行爬取,BeautifulSoup 模块的使用方法可以参照 BeautifulSoup 模块使用指南

    “热门” 目录每页有 20 篇文章,底部有一个 “点击查看更多” 的按钮,此按钮对应一个 data-url 用于加载下一页的文章。爬取当前页面的所有文章后,提取页面底部的 data-url ,再爬取对应 URL 页面的文章,依此步骤递归爬取,可以获得 “热门” 目录中的所有文章。爬取到文章的信息有“文章ID”,“文章标题”,“文章URL”,“作者”,“作者的URL”,“缩略图URL”,“文章内容”,“发表时间”,“阅读数”,“评论数”,“喜欢”,“打赏”,“热门”目录每一小时爬取一次。

    代码中使用 Django orm 来生成所需要的数据库,若不熟悉 Django,请参阅官方文档 Django 官方文档 或者对应的 中文翻译文档。数据库设计代码参考 jianshu 目录下 models.py 文件,爬虫代码参考 popular_articles_jianshu.py 文件。


    3. 爬取简书新上榜的文章

    对于新上榜中的内容,每次只爬取当前页面中的所有文章,15 分钟爬取一次,不会递归爬取所有页,API 分为文章概要和文章详细信息,文章概要包含“文章ID”,“文章标题”,“文章URL”,“作者”和“作者的URL”,文章详细信息包括“缩略图URL”,“文章标题”,“文章内容”,“发表时间”,“阅读数”,“评论数”,“喜欢”,“打赏”,API 每次返回 18 篇文章的信息。


    4. 爬取搜索到的文章

    本来想爬取简书中某一类技术文章,由于简书没有明显的分类目录,文章也没有对应的 tag 所以准备爬取搜索到的文章。

    下面以搜索 python 为例说明,用 chrome 的开发者者工具可以查看到请求的 URL 以及 response 的数据。

    这是搜索时用到的 URLhttp://www.jianshu.com/search/do?q=python&page=1&type=notesq=python 表示搜索的关键字是 pythonpage 表示的是页数,但是在爬取时只能爬取前 100 页,每页 10 条数据,后面的文章请求不到,在浏览器中也无法查看。


    搜索文章

    下面的是 response 的数据,也正是我们要抓取的内容。


    响应的数据

    请求到每页的数据如下所示:

    {"q":"python","page":1,"type":"notes","total_count":9993,"per_page":10,"total_pages":100,"entries":
    [{"id":2851052,"title":"<em class='search-result-highlight'>Python</em>",
    "slug":"e1a9af9b48a4","content":"……编码风格 \n  PEP8   PEP0257   
    <em class='search-result-highlight'>Python</em>之禅  \n 招聘 \n  
    <em class='search-result-highlight'>Python</em>招聘需求与技能体系  \n 
    <em class='search-result-highlight'>Python</em>库 \n  Awesome <em class='search-result-highlight'>Python</em>……",
    "user":{"id":857942,"nickname":"被欺负的大白","slug":"175b9cfd71fb"},
    "notebook":{"id":3010085,"name":"资源收集"},"public_comments_count":0,"likes_count":13,"views_count":960,"total_rewards_count":0,
    "first_shared_at":"2016-01-17T12:16:54.000Z"},
    

    返回的数据是字符串类型的 JSON 数据,先将其强制转换为 dict,然后从 entries 属性中获取文章的详细信息。代码请查看 GitHub 项目下 update_search_jianshu.py 文件。

    代码中存在的问题:简书设置未登录用户 10 秒中只能搜索一次,目前还没有加入绕过登录的功能,可以在请求时加入 cookie 文件绕过登录,或者向其登录表单提交账号认证。

    5. 生成 API

    将上面爬取到的文章保存到 MySQL 中,使用 Django REST framework 来生成 API,若对此功能不熟悉的请查 Django REST framework 官方文档


    简书 API

    6. 部署上线

    • 使用 nginx + uwsgi + django + supervisor 进行环境部署
      或者
    • 使用 docker 进行环境部署

    相关文章

      网友评论

      • 地瓜番薯:测试地址打开,怎么需要登录呀
        田飞雨:@地瓜番薯 没有
        地瓜番薯:@田飞雨 有临时api地址吗,我想用简书api做一个应用
        田飞雨:@地瓜番薯 这个已经不再维护了,地址有问题
      • 魔攻力缆狂澜聊:我也想抱大腿············· :heart_eyes:
        田飞雨:@986ed3f3eb34 :sweat:
      • fendo:赞一个!!
      • Mikesong:求加好友,可以么。最近学python有点不会
        田飞雨: @Mikesong 可以,看我资料有个人网站,网站首页有加群链接
      • 职场求生必备:爬搜索的文章,比如python的。http://www.jianshu.com/search?q=python&page=100&type=notes,左上角有文章数量,直接获取数量/10,然后替换链接中的page=后面的数字,这样不行吗?
        田飞雨: @父母心网 代码在后面那几节呢,你用requests模块请求那个url看返回数据是否正常
        职场求生必备:@田飞雨 直接在浏览器改URL是可以实现的啊。能贴段代码一起研究下?
        田飞雨:@父母心网 测试过不行,每次都返回第一页的数据
      • Windream:很好,正好自己想学习做api
        田飞雨:@Windream 做起来挺简单的,但是有些东西我还没弄懂
      • weiman:作者你好,请问如何做到在首页,七天热门,新上榜之间做切换呐?我发现它们的url都是www.jianshu.com,而浏览器查到的payload又是乱码
        weiman:哦哦,其实是跳转到了,只是网页的标识还停在“热门”按钮上 :smiley:
        weiman:嗯嗯,我试了一下,当我在主页点击“七日热门”的话,浏览器顶部的地址栏还是www.jianshu.com。用开发者工具Network发现点击后有一个get请求是指向http://www.jianshu.com/trending/weekly?_=1469887979768。但是当我在浏览器复制这个地址进去的话显示的还是主页,没有跳转到七日热门
        田飞雨:@weiman 你用 chrome 开发者工具看看,URL 其实都不是 www.jianshu.com
      • d2b790dd5247:最近很想学习可是不知道怎么学。。。
        田飞雨:@东东lo 来报啊 :smile:
        d2b790dd5247:@田飞雨 求抱大腿:heart_eyes:
        田飞雨:@东东lo 跟我学

      本文标题:爬取简书全站文章并生成 API(一)

      本文链接:https://www.haomeiwen.com/subject/aoeojttx.html