知乎图片爬虫

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011659379/article/details/53020704

好久没写csdn博客了,觉得不应该把这个博客荒废了,那就继续写吧。
这回写写知乎爬虫,主要是写模拟登录知乎,以及爬知乎图片。

本篇文章分为两个部分:
1. 模拟登录知乎
2. 爬取知乎某个问题下的所有回答里面的照片。

1. 模拟登录知乎

首先我们打开知乎

我们采用chrome浏览器自带的开发者工具进行抓包。
按F12打开开发者工具,选择Network,然后筛选XHR,如图所示

接着填入账号密码,进行点击登录记住点了登录之后,要及时按暂停,不然就跳转到登陆后的页面了!抓到的数据如下图

可以看到知乎模拟登录的过程是向https://www.zhihu.com/login/phone_num 这个网址post提交

_xsrf:154ccc9a95fa9f8c7612608e2fd07aa5
password:密码
captcha_type:cn
remember_me:true
phone_num:账号

其中_xsrf是一个动态的参数,我们打开任意一个知乎的页面,比如http://www.zhihu.com,然后查看源代码,都可以找到_xsrf这个参数

同时,我们观察一下post提交的网址:https://www.zhihu.com/login/phone_num ,结尾是 phone_num
这里说明一下,因为我这里使用手机号登录的,所以提交网址时这个。
如果使用邮箱登录的,post提交的网址就是https://www.zhihu.com/login/email
且提交的数据中phone_num就成为email了。

有时候登录知乎会遇到验证码,验证码是个很讨厌的东西,如果是简单的4字验证码还好,如果是这种

对不起,我讲不下去了!尼玛知乎的验证码升级了!!!
所以我直接发之前的代码吧,说不定还能用。。。
—5分钟后更新—
^_^脚本还能用!模拟登录的时候验证码没有那么变态~~不过既然代码发出来了,我就不继续讲了。有空再填坑

#-*- coding=utf-8 -*- 
"""
知乎图片下载器
"""
import requests
import re
import json
import time
from PIL import Image
import cStringIO
import cookielib  
import urllib
import os

api_url='https://www.zhihu.com/node/QuestionAnswerListV2'
login_url='https://www.zhihu.com/login/'
topic_url='https://www.zhihu.com/question/'


headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
}

session=requests.Session()
session.headers=headers    
session.cookies = cookielib.LWPCookieJar(filename='cookies') 
try:  
    session.cookies.load(ignore_discard=True)  
except:  
    print u"未登陆过,需先登录"  


def get_xsrf(url="http://www.zhihu.com"):  
    '''''_xsrf 是一个动态变化的参数'''  
    global session
    index_url =  url
    index_page = session.get(index_url)  
    html = index_page.content  
    pattern = r'name="_xsrf" value="(.*?)"'  
    _xsrf = re.findall(pattern, html)  
    return _xsrf[0]


def ImageScale(url,session=None):
    if session==None:
        session=requests.Session()
    file = cStringIO.StringIO(session.get(url).content)
    img = Image.open(file)
    img.show()


def get_captcha():
    global session
    t=str(int(time.time()*1000))
    captcha_url='https://www.zhihu.com/captcha.gif?r=%s&type=login'%t
    print captcha_url
    ImageScale(captcha_url,session)
    print u'请输入验证码:'
    yzm=raw_input()
    return yzm

def isLogin():  
    global session
    url = "https://www.zhihu.com/settings/profile"  
    login_code = session.get(url, allow_redirects=False).status_code  
    if int(x=login_code) == 200:  
        return True  
    else:  
        return False 

def login(email,passwd):
    global session
    isemail=re.search('@',email)
    if isemail:
        loginurl=login_url+'email'
        data={'_xsrf':get_xsrf()
                ,'password':passwd
                ,'remember_me':'true'
                ,'email':email}
    else:
        loginurl=login_url+'phone_num'
        data={'_xsrf':get_xsrf()
                ,'password':passwd
                ,'remember_me':'true'
                ,'phone_num':email}
    try:
        login_page=session.post(loginurl,data=data)
        login_code=login_page.content
        print login_page.status
        print login_code
    except:
        data['captcha']=get_captcha()
        login_page=session.post(loginurl,data=data)
        login_code=json.loads(login_page.content)
        print login_code['msg']
    session.cookies.save()


def get_pic_from_topic(id,offset):
    global session
    topicurl=topic_url+str(id)
    _xsrf=get_xsrf(topicurl)
    pic_re=re.compile('data-actualsrc="(.*?)"')
    inner_data={"url_token":id
                ,"pagesize":10
                ,"offset":offset
                }
    data={'method':'next'
        ,'params':json.dumps(inner_data)
        }
    session.headers['Referer']=topicurl
    session.headers['Host']='www.zhihu.com'
    session.headers['Origin']='https://www.zhihu.com'
    session.headers['X-Xsrftoken']=_xsrf
    js_data=session.post(api_url,data=data)
    dat=json.loads(js_data.content)['msg']
    pictures=[]
    for d in dat:
        pics=pic_re.findall(d)
        pictures.extend(pics)
    return pictures

def downloader(url,path):
    try:
        filename=url.split('/')[-1]
        save=os.path.join(path,filename)
        print u'开始下载 ',filename
        urllib.urlretrieve(url,filename=save)
    except Exception,e:
        print u'下载出错,错误信息为:'
        print e


if __name__=='__main__':
    email='知乎账号'
    passwd='知乎密码'
    is_login=isLogin()
    if not is_login:
        login(email,passwd)
    offset=0
    pictures=[]
    print u"""####################\n#  知乎图片下载器  #\n####################      
            """
    print u"请输入知乎问题id,比如https://www.zhihu.com/question/52049909,id就是52049909"
    id=input()
    print u'=====开始解析======'
    while 1:
        print u"+++++正在解析第%d页+++++"%(offset/10+1)
        pics=get_pic_from_topic(id,offset)
        if len(pics)==0:
            print u"解析完毕,共找到%d张图片"%len(pictures)
            break
        pictures.extend(pics)
        offset+=10
    print u"=====开始下载图片====="
    basepath=os.path.abspath('.')
    savepath=os.path.join(basepath,str(id))
    if not os.path.exists(savepath):
        os.mkdir(savepath)
    for pic in pictures:
        downloader(pic,savepath)
    print u"=====下载完毕====="

猜你喜欢

转载自blog.csdn.net/u011659379/article/details/53020704