美文网首页程序员今日看点
分析一个爬虫的分页问题

分析一个爬虫的分页问题

作者: 向右奔跑 | 来源:发表于2017-02-14 23:52 被阅读1279次

    接着这篇《Python爬取数据的分页分析》,最后的难点地方:滚动分页,不知道总页数的情况,如何确定爬虫的分页抓取。

    以简书的“个人主页”-- “动态”为例来说明。

    先看一下“个人动态”中有哪些数据:评论,喜欢,打赏,关注(作者、专题)(这些都指的是对他人的文章),发表文章(自己),还有一个重要数据“加入简书”(注册时间)。

                ## 用户行为类型 
                ## share_note 发表文章
                ## like_collection 关注专题
                ## comment_note 发表评论
                ## like_comment 赞了评论
                ## reward_note 打赏文章
                ## like_user 关注作者
    

    再看一下网页结构,在个人主页下 看动态,是一个tab切换,有 文章 -- 动态 -- 最新评论 -- 热门,默认情况下,看到的是“文章”这个tab,切换到“动态”tab下,就可以看到用户在简书上一系列的行为操作和时间。不断下拉滚动条,看到所有记录,最后一条是用户的注册时间。

    一个典型的滚动分页,不知道总页数。那爬虫如何确定分页的URL,抓取到所有数据呢?

    特别注意,因为这个页面采用的框架页,进到用户主页,切换到“动态”tab,查看源代码,是看不到“动态”内容的源代码的。这个也给我们确定分页的URL中的参数造成难题。

    还是用Chrome -- 检查 -- Network 工具来分析一下 第2页,第3页的URL,找找规律:

    这是第2页URL:

    http://www.jianshu.com/users/1441f4ae075d/timeline?max_id=97250697&page=2  
    

    第3页URL:

    http://www.jianshu.com/users/1441f4ae075d/timeline?max_id=94439065&page=3
    

    基本可以确定,分页URL是userid/timeline?max_id=xxx&page=x,URL中需要这样两个参数:max_id和page,max_id是什么鬼,这个就是这里分页的最关键的地方,还有一共有多少页怎么确定,也就是爬虫需要递归调用多少次才结束。

    还有一点,需要同时看一下,第2页、第3页分页返回的是xml数据(一段网页代码),也就是这时最大程度复用了页面,用的Ajax。

    第一步,先确定max_id,还是要到页面源代码中找蛛丝马迹,如果按照一开始进到用户主页,切到“动态”tab,别说max_id找不到,就连页面的那些内容也找不到。陷入僵局的状态。这个max_id看名字就不像时间戳,而像是页面开始的数据id。

    关键原因是框架页面挡住了我们的视线,把第2页、第3页的URL直接粘到地址栏回车,查看源代码,一切都有了。

    把刚刚分页URL中的那个max_id搜一下,有木有。我的猜想是最后一个id。顺着这个思路往下就比较好弄了。关键是拿出

    <li class="" id="feed-93167794">
    

    当中的id去构造一个分页URL就行了,然后顺序往下翻,直到最后一页为止。

    不细说了,如何确定max_id,如何提取max_id,如何确定最后一页。

    好啦,我直接上源码:

    #coding=utf-8
    import requests
    from lxml import etree
    
    ## 抓取用户timeline数据
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
    }
    
    def get_info(url,page):
    
        uid   = url.split('/')
        uid   = uid[4]
    
        if url.find('page='):
            page = page+1
    
        html = requests.get(url,headers=headers).content
        selector = etree.HTML(html)
    
        infos2 = selector.xpath('//ul[@class="note-list"]/li/@id')
    
        infos = selector.xpath('//ul[@class="note-list"]/li')
        for info in infos:
            name = info.xpath('div/div/div/a/text()')[0]
            dd = info.xpath('div/div/div/span/@data-datetime')[0]
            type = info.xpath('div/div/div/span/@data-type')[0]
            print type
            print dd
    
        if len(infos) > 1:
            tid = infos2[len(infos2) - 1]
            tid = int(filter(str.isdigit, tid)) - 1
            print tid
    
            next_url = 'http://www.jianshu.com/users/%s/timeline?max_id=%s&page=%s' % (uid, tid, page)
    
            
            get_info(next_url,page)
    
    
    get_info('http://www.jianshu.com/users/54b5900965ea/timeline',1)
    
    
    

    Github: https://github.com/ppy2790/author/, 可以比较一下Scrapy 和直接用 requests 两种方式的代码有什么不同。

    经验:大胆设想,小心求证,简化处理,认真查找,反复折腾

    相关文章

      网友评论

        本文标题:分析一个爬虫的分页问题

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