第二个爬虫之爬取知乎用户动态并将所有动态内容保存到txt文件中

不打扰是莪最后的温柔 提交于 2019-12-03 20:55:36

自从这两天开始学爬虫,就一直想做个爬虫爬知乎。于是就开始动手了。

知乎用户动态采取的是动态加载的方式,也就是先加载一部分的动态,要一直滑道底才会加载另一部分的动态。要爬取全部的动态,就得先获取全部的url。

我先找到了第一条url:

https://www.zhihu.com/api/v4/members/***************************/activities?limit=7&session_id=************************&after_id=*************&desktop=True
为了不泄露别人的隐私。涉及到用户信息部分我都用*来代替。
通过几个url的比对,我找到个关键的信息after_id。
这个after_id是一串n位的数字,刚开始我以为每条url之间的after_id都是有规律的,但对比了几条url之后我发现这个数字完全没有规律。那没有规律的话该怎么找出下一个url呢?
情急之下我想到一个办法,我发现after_id前几位是不变的,一直改变的是后六位数字。于是我想到,能不能遍历十万个数,每次after_id加一,这样就能找出所有的url了。
这不太可行。
冷静下来我开始分析url。打开url之后我发现回复的json数据里有一个键值‘next’,里面放的就是下一次请求的url。只要不断提取next的值,就能拿到所有的url。于是我想到了递归的方法。难点解决了,剩下的其实很快就可以完成。下面的源码:
import re
import os
import requests
import urllib
import json
allUrl=[]       #全局数组,用来保存该用户所有的动态的urldef getUrl(url):    #递归获取用户所有的动态url
    nextUrl=urllib.request.urlopen(url)
    nextUrl=json.loads(nextUrl.read())
    key=nextUrl['paging']
    if 'next' in key:   #假如还没到底
        nextUrl=nextUrl['paging']['next']
        allUrl.append(nextUrl)
        #print(nextUrl)
        getUrl(nextUrl)
    else:      #已经到底,停止递归
        print('成功获取所有url!')
        return    

def getArticle():     #获取文章,并将文章存入文本文件中
    a=''
    cnt=0
    for line in allUrl:    
        t=urllib.request.urlopen(line)
        t=json.loads(t.read())
        t=t['data']
        try:    #异常处理,由于未知原因,爬取某个url时会出现找不到json数据里的content键,导致报错
            for k in t:    #提取单个url内所有文章
                k1=k['target']['content']
                k1=re.sub('.*?</figure>','\r\n\r\n',k1)
                k1=k1.replace('</p><p>','\r\n    ')
                k1=k1.replace('</p>','\r\n')
                k1=k1.replace('<p>','')
                k1=k1.replace('<br>','')
                cnt=cnt+1
                a=a+k1
                print('第'+str(cnt)+'个动态爬取成功')
        except KeyError:
            print('发生错误,此时的url为'+str(line))    
                  
    file=open('D:/bbb.txt','w',encoding='gb18030',errors='ignore')  #将内容写入文本,字符编码要与浏览器一致,否则会报错。
    file.write(a)
    file.close()        


getUrl(url)     #参数是第一个url
getArticle()

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!