scrapy爬取知乎问题实战

首先,需要理解cookies的含义,是存储在浏览器中的内容,在本地存储任意键值对,第一次访问时服务器返回一个id存储到本地cookie中,第二次访问将cookies一起发送到服务器中

常见http状态码

code 说明
200 请求成功
301/302 永久重定向/临时重定向
403 没有权限访问
404 没有对应的资源
500 服务器错误
503 服务器停机或正在维护

要爬取知乎内容首先需要进行登录,在本文中我们主要介绍2种登录方式,第一种是通过requests的session保存cookies进行登录,第二种是通过scrapy修改start_requests函数进行登录

<!--more-->

requests进行登录

在utils中新建zhihu_login.py,实例化一个session对象,设置其cookies对象为cookiesjar库中的LWPCookieJar对象,设置requests库需要用到的headrs(从浏览器中进行拷贝),

session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='zhihu_cookies.txt')
headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
        'Origin':'https://www.zhihu.com',
        'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
        'Host':'www.zhihu.com',
        'Referer':'https://www.zhihu.com/'
}

接下来,我们要寻找登录发送数据的页面,首先打开zhihu.com退出之前的登录,来到一个登录页面,在登陆页面中使用手机号码登录,此时需要发送一个错误的信息给页面,以找到post数据的网页(如果输入正确的账号密码就直接登录成功了,一大堆网页请求就找不到我们需要的网页了)

找到了需要post的网页,发现post的数据有_xsrf,passoword,phone_num,另外一个captcha_type没有用,加了之后反而无法访问(不知道为什么)

def zhihu_login(account, password):
    if re.match('1\d{10}', account):
        phone_post_url = 'https://www.zhihu.com/login/phone_num'
        post_data={
            '_xsrf':get_xsrf(),
            'phone_num':account,
            'password':password,
            # 'captcha_type':'cn'
        }
        # session_response = session.post(phone_post_url, data=post_data, headers=header)
        # print(session_response.text)
        # result_list = re.findall('"msg": "(.*?)"',session_response.text)[0]
        # print(result_list.encode('utf8').decode('unicode-escape'))
        # try:
        #     login_page = session.post(phone_post_url, data=post_data, headers=headers)
        #     print('不要验证码,login_code:{}'.format(login_page.status_code))
        # except:
        post_data['captcha'] = get_captcha()
        login_page = session.post(phone_post_url, data=post_data, headers=headers)
        result_list = re.findall('"msg": "(.*?)"', login_page.text)[0]
        print(result_list.encode('utf8').decode('unicode-escape'))
        session.cookies.save()
        print('保存成功')

在这里我们一开始没有使用验证码,发现只要是爬虫登录都会被识别到,所以我们编写了一个用于生成验证码的代码:


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)
    try:
        im = Image.open('captcha.jpg')
        im.show()
        im.close()
    except:
        print('wrong')
    captcha = input('请输入验证码:')
    return captcha

保存完cookies,我们尝试使用这个cookies再次登录


def get_again():
    try:
        session.cookies.load(ignore_discard=True)
        print('cookies加载成功\n')
    except:
        print('cookies加载失败')
    response = session.get('https://www.zhihu.com',headers=headers)
    # response.encoding = response.apparent_encoding
    with open('my_zhihu_login.html','wb') as f:
        f.write(response.text.encode('utf8'))
        print('保存页面成功')

查看这个页面发现不停地刷新,暂时还没有找到办法

scrapy模拟登陆知乎

首先生成一个新的spider,名字为zhihu

在class zhihu中定义headers等信息,重写start_requests函数


def start_requests(self):
     return [scrapy.Request('https://www.zhihu.com/#signin',headers=self.headers, callback=self.login)]

start_requests里面返回一个新的Request,其回调函数设置为一个新的login函数如下:


def login(self,response):
  # print(response.text)
  # a = '<input type="hidden" name="_xsrf" value="36424865b408db8c3f976a1a676cad60"/>'
  match_obj = re.match('.*name="_xsrf" value="(.*?)"', response.text, re.DOTALL)
  if match_obj:
    _xsrf = match_obj.group(1)
    post_data = {
      '_xsrf': _xsrf,
      'phone_num': 'xxxxxxxxxxx',
      'password': 'xxxxxxx',
      'captcha':''
    }
    t = str(int(time.time() * 1000))
    captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
    return [scrapy.Request(url=captcha_url,
                           meta={'post_data':post_data},
                           headers=self.headers,
                           callback=self.get_captcha_login)]

  else:
    raise EOFError

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 模拟爬虫抓取知乎用户信息以及人际拓扑关系,使用scrapy爬虫框架,数据存储使用mongo数据库。   本地运行请注意:爬虫依赖mongo和rabbitmq,因此这两个服务必须正常运行和配置。为了加快下载效率,图片下载是异步任务,因此在启动爬虫进程执行需要启动异步worker,启动方式是进入zhihu_spider/zhihu目录后执行下面命令:   celery -A zhihu.tools.async worker --loglevel=info   爬虫项目部署:   进入zhihu_spider后执行```docker-compose up``` ,进入container后和本地运行方法相同,依次启动mongo、rabbitmq、异步任务、爬虫进程即可。   其它需要说明的问题:   爬虫框架从start\_requests开始执行,此部分会提交知乎主页的访问请求给引擎,并设置回调函数为post_login.   post\_login解析主页获取\_xsrf保存为成员变量中,并提交登陆的POST请求,设置回调函数为after\_login.   after\_login拿到登陆后的cookie,提交一个start\_url的GET请求给爬虫引擎,设置回调函数parse\_people.   parse\_people解析个人主页,一次提交关注人和粉丝列表页面到爬虫引擎,回调函数是parse\_follow, 并把解析好的个人数据提交爬虫引擎写入mongo。   parse\_follow会解析用户列表,同时把动态的人员列表POST请求发送只引擎,回调函数是parse\_post\_follow,把解析好的用户主页链接请求也发送到引擎,人员关系写入mongo。   parse\_post\_follow单纯解析用户列表,提交用户主页请求至引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值