最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • python爬虫如何获取知乎问答内容?

    正文概述    2020-10-01   470

    python爬虫如何获取知乎问答内容?

    有疑问和困惑的时候,除了去书本翻阅资料,还可以在知乎上发起提问,和来自不同地方的小伙伴一起进行讨论。小编觉得这种学习的方法不仅能够自己理解知识,而且别人也会在回答中有所提升,是个一举两得的好办法。最近小编想把问答的内容收集起来留着学习,小伙伴们也可以跟着小编一起学习收集的方法。


    爬取知乎的关键的部分:模拟登陆

    通过对知乎登陆是的抓包,可以发现登陆知乎,需要post三个参数,一个是账号,一个是密码,一个是xrsf。

    这个xrsf隐藏在表单里面,每次登陆的时候,应该是服务器随机产生一个字符串。所有,要模拟登陆的时候,必须要拿到xrsf。

    用chrome (或者火狐 httpfox 抓包分析)的结果:

    python爬虫如何获取知乎问答内容?

     

    所以,必须要拿到xsrf的数值,注意这是一个动态变化的参数,每次都不一样。


    python爬虫如何获取知乎问答内容?

     

    注意findallfind_all函数的区别。

    拿到xsrf,下面就可以模拟登陆了。

    使用requests库的session对象,建立一个会话的好处是,可以把同一个用户的不同请求联系起来,直到会话结束都会自动处理cookies。

    def login(secret, account):
        # 通过输入的用户名判断是否是手机号
        if re.match(r"^1\d{10}$", account):
            print("手机号登录 \n")
            post_url = 'https://www.zhihu.com/login/phone_num'
            postdata = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'phone_num': account,
            }
        else:
            if "@" in account:
                print("邮箱登录 \n")
            else:
                print("你的账号输入有问题,请重新登录")
                return 0
            post_url = 'https://www.zhihu.com/login/email'
            postdata = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'email': account,
            }
        try:
            # 不需要验证码直接登录成功
            login_page = session.post(post_url, data=postdata, headers=headers)
            login_code = login_page.text
            print(login_page.status_code)
            print(login_code)
        except:
            # 需要输入验证码后才能登录成功
            postdata["captcha"] = get_captcha()
            login_page = session.post(post_url, data=postdata, headers=headers)
            login_code = eval(login_page.text)
            print(login_code['msg'])
        session.cookies.save()
    try:
        input = raw_input
    except:
    Pass

      

    这是登陆的函数,通过login函数来登陆,post 自己的账号,密码和xrsf 到知乎登陆认证的页面上去,然后得到cookie,将cookie保存到当前目录下的文件里面。下次登陆的时候,直接读取这个cookie文件。

    #LWP-Cookies-2.0
    Set-Cookie3: cap_id="\"YWJkNTkxYzhiMGYwNDU2OGI4NDUxN2FlNzBmY2NlMTY=|1487052577|4aacd7a27b11a852e637262bb251d79c6cf4c8dc\""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:37Z"; version=0
    Set-Cookie3: l_cap_id="\"OGFmYTk3ZDA3YmJmNDQ4YThiNjFlZjU3NzQ5NjZjMTA=|1487052577|0f66a8f8d485bc85e500a121587780c7c8766faf\""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:37Z"; version=0
    Set-Cookie3: login="\"NmYxMmU0NWJmN2JlNDY2NGFhYzZiYWIxMzE5ZTZiMzU=|1487052597|a57652ef6e0bbbc9c4df0a8a0a59b559d4e20456\""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:57Z"; version=0
    Set-Cookie3: q_c1="ee29042649aa4f87969ed193acb6cb83|1487052577000|1487052577000"; path="/"; domain=".zhihu.com"; path_spec; expires="2020-02-14 06:09:37Z"; version=0
    Set-Cookie3: z_c0="\"QUFCQTFCOGdBQUFYQUFBQVlRSlZUVFVzeWxoZzlNbTYtNkt0Qk1NV0JLUHZBV0N6NlNNQmZ3PT0=|1487052597|dcf272463c56dd6578d89e3ba543d46b44a22f68\""; path="/"; domain=".zhihu.com"; path_spec; expires="2017-03-16 06:09:57Z"; httponly=None; version=0
     
    这是cookie文件的内容
    以下是源码:
     
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import requests
    try:
        import cookielib
    except:
        import http.cookiejar as cookielib
    import re
    import time
    import os.path
    try:
        from PIL import Image
    except:
        pass
    from bs4 import BeautifulSoup
    # 构造 Request headers
    agent = 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0'
    headers = {
        "Host": "www.zhihu.com",
        "Referer": "https://www.zhihu.com/",
        'User-Agent': agent
    }
    # 使用登录cookie信息
    session = requests.session()
    session.cookies = cookielib.LWPCookieJar(filename='cookies')
    try:
        session.cookies.load(ignore_discard=True)
    except:
        print("Cookie 未能加载")
    def get_xsrf():
        '''_xsrf 是一个动态变化的参数'''
        index_url = 'https://www.zhihu.com'
        # 获取登录时需要用到的_xsrf
        index_page = session.get(index_url, headers=headers)
        html = index_page.text
        pattern = r'name="_xsrf" value="(.*?)"'
        # 这里的_xsrf 返回的是一个list
        _xsrf = re.findall(pattern, html)
        return _xsrf[0]
    # 获取验证码
    def get_captcha():
        t = str(int(time.time() * 1000))
        captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
        r = session.get(captcha_url, headers=headers)
        with open('captcha.jpg', 'wb') as f:
            f.write(r.content)
            f.close()
        # 用pillow 的 Image 显示验证码
        # 如果没有安装 pillow 到源代码所在的目录去找到验证码然后手动输入
        try:
            im = Image.open('captcha.jpg')
            im.show()
            im.close()
        except:
            print(u'请到 %s 目录找到captcha.jpg 手动输入' % os.path.abspath('captcha.jpg'))
        captcha = input("please input the captcha\n>")
        return captcha
    def isLogin():
        # 通过查看用户个人信息来判断是否已经登录
        url = "https://www.zhihu.com/settings/profile"
        login_code = session.get(url, headers=headers, allow_redirects=False).status_code
        if login_code == 200:
            return True
        else:
            return False
    def login(secret, account):
        # 通过输入的用户名判断是否是手机号
        if re.match(r"^1\d{10}$", account):
            print("手机号登录 \n")
            post_url = 'https://www.zhihu.com/login/phone_num'
            postdata = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'phone_num': account,
            }
        else:
            if "@" in account:
                print("邮箱登录 \n")
            else:
                print("你的账号输入有问题,请重新登录")
                return 0
            post_url = 'https://www.zhihu.com/login/email'
            postdata = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'email': account,
            }
        try:
            # 不需要验证码直接登录成功
            login_page = session.post(post_url, data=postdata, headers=headers)
            login_code = login_page.text
            print(login_page.status_code)
            print(login_code)
        except:
            # 需要输入验证码后才能登录成功
            postdata["captcha"] = get_captcha()
            login_page = session.post(post_url, data=postdata, headers=headers)
            login_code = eval(login_page.text)
            print(login_code['msg'])
        session.cookies.save()
    try:
        input = raw_input
    except:
        pass
    ## 將main的問題列表輸出在shell上面
    def  getPageQuestion(url2):  
      mainpage = session.get(url2, headers=headers)
      soup=BeautifulSoup(mainpage.text,'html.parser')
      tags=soup.find_all("a",class_="question_link")
      #print tags
      for tag in tags:
        print tag.string
    # 將main頁面上面的問題的回答的摘要輸出在shell上面
    def getPageAnswerAbstract(url2):
        mainpage=session.get(url2,headers=headers)
        soup=BeautifulSoup(mainpage.text,'html.parser')
        tags=soup.find_all('div',class_='zh-summary summary clearfix')
        for tag in tags:
           # print tag
            print tag.get_text()
            print '詳細內容的鏈接 :',tag.find('a').get('href')
    def getPageALL(url2):
        #mainpage=session.get(url2,headers=headers)
        #soup=BeautifulSoup(mainpage.text,'html.parser')
        #tags=soup.find_all('div',class_='feed-item-inner')
        #print "def getpageall "
        mainpage=session.get(url2,headers=headers)
        soup=BeautifulSoup(mainpage.text,'html.parser')
        tags=soup.find_all('div',class_='feed-content')
        for tag in tags:
            #print tag
            print tag.find('a',class_='question_link').get_text()
            # 這裏有一點問題 bs 還是用的不是太熟練
            #print tag.find('a',class_='zh-summary summary clearfix').get_text()
            #print tag.find('div',class_='zh-summary summary clearfix').get_text()
    if __name__ == '__main__':
        if isLogin():
            print('您已经登录')
            url2='https://www.zhihu.com'
            # getPageQuestion(url2)
            #getPageAnswerAbstract(url2)
            getPageALL(url2)
        else:
            account = input('请输入你的用户名\n>  ')
            secret = input("请输入你的密码\n>  ")
            login(secret, account)

    不得不说想要获取知乎问答的内容是一项复杂的操作,为了学好python我们也要任重而道远了。虽然内容很多,小伙伴跟着步骤操作应该是没有什么问题的。更多Python学习推荐:起源地模板网教学中心




    起源地下载网 » python爬虫如何获取知乎问答内容?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元