百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python爬虫教程:爬取知乎网

wxin55 2024-11-17 16:53 8 浏览 0 评论

知乎已经成为了爬虫的训练场,本文利用Python中的requests库,模拟登陆知乎,获取cookie,保存到本地,然后这个cookie作为登陆的凭证,登陆知乎的主页面,爬取知乎主页面上的问题和对应问题回答的摘要。

关于知乎验证码登陆的问题,用到了Python上一个重要的图片处理库PIL,如果不行,就把图片存到本地,手动输入。

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

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

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

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

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

注意findall和find_all函数的区别。

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

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

注意:cookies 是当前目录的一个文件,这个文件保存了知乎的cookie,如果是第一个登陆,那么当然是没有这个文件的,不能通过cookie文件来登陆。必须要输入密码。


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学习交流群,可以交流学习拓展人脉。

相关推荐

总结雅虎前端性能优化技巧(16条)

前言在日常开发中,有很多场景需要我们去做好前端优化,为了防止遗忘,加深记忆,今天参阅了一些资料以及自己的一些总结,梳理出来15条优化技巧。1.合并文件css、js合并,减少http请求数,每次http...

前端掉坑血泪史!4 个 React 性能优化绝招让页面秒开

在前端圈子里摸爬滚打这么多年,我发现React开发时踩坑的经历大家都大同小异。页面加载慢、组件频繁重渲染、状态管理混乱……这些痛点,相信不少前端工程师都感同身受。别愁!今天就给大家分享4个超...

Qwik:革新Web开发的新框架

听说关注我的人,都实现了财富自由!你还在等什么?赶紧加入我们,一起走向人生巅峰!Qwik:革新Web开发的新框架Qwik橫空出世:一场颠覆前端格局的革命?是炒作还是未来?前端框架的更新迭代速度,如同...

大模型服务平台百炼使用

提供完整的模型训练、微调、评估等产品工具,预置丰富的应用插件,提供便捷的集成方式,更快更高效地完成大模型应用的构建。一、通过变量的方式使用平台模板一个好的Prompt可以更好的让模型理解我们的需求,产...

Vue应用性能优化实战:8 个提升页面加载速度的关键策略

一、构建优化与代码精简1.1代码分割与异步加载路由级代码分割:使用动态导入语法拆分路由组件组件级懒加载:结合Suspense实现按需加载javascript//vue-router4.x配置...

前端里那些你不知道的事儿之 【window.onload】

作者:京东科技孙凯一、前言相信很多前端开发者在做项目时同时也都做过页面性能优化,这不单是前端的必备职业技能,也是考验一个前端基础是否扎实的考点,而性能指标也通常是每一个开发者的绩效之一。尤其马上接近...

谷歌站长后台的“核心网页指标”不合格先优化哪个最有效?

根据对上千个网站案例的分析,90%的站长在修复时都陷入“盲目优化”误区——要么死磕服务器配置却忽略图片规范,要么过度压缩JS反而引发CLS布局错位。事实上,移动端页面抖动(CLS)才是60%中小网站的...

Vue3 开发效率拉胯?这 10 个技巧让你开发速度翻倍!

写Vue3项目时,是不是经常被数据更新延迟、组件间传值混乱、页面卡顿这些问题搞得焦头烂额?别担心!今天带来10个超实用的Vue3实战技巧,全是从真实项目中总结出来的“血与泪”经验,帮你...

2024年的JavaScript性能优化:仍然重要吗?

#记录我的9月生活#在不断发展的Web开发领域,新的JavaScript框架和库令人眼花缭乱,很容易让人忽视一些基本的东西。但在这股兴奋之中,性能作为一个卓越用户体验的基石,不能被忽略。为什么?因为...

JS 图片简易压缩【实践】

作者:政采云前端团队转发链接:https://juejin.im/post/5ea574cc518825736e57fcca前言说起图片压缩,大家想到的或者平时用到的很多工具都可以实现,例如,客户端类...

Vue3 开发总踩坑?这 10 个技巧让你少走半年弯路!

前端开发的路上,Vue3虽然强大,但坑也不少!性能优化总没效果?复杂组件通信一头雾水?别担心!今天分享10个超实用的Vue3实战技巧,全是一线开发总结的经验,帮你轻松避开开发雷区,效率直接拉...

前端分享-Vue首屏加载优化

首屏加载速度直接影响用户留存率——当加载时间超过3秒,53%的用户会直接离开(网上来的数据)。Vue单页应用尤需重视,因为传统打包方案会将所有资源打包成巨大的vendor.js,导致用户首次访问时像下...

Core Web Vitals 变了,网站性能这件事得重新关注

现在做网站优化,不能只看速度条,不管你是搞外贸独立站,还是给品牌建站,体验页面这件事你迟早得面对。谷歌这两年把网站的“体验感”提得越来越多,尤其是CoreWebVitals(网页核心指标)一出来,...

页面卡顿到崩溃?5 个实战技巧让前端性能飙升 80%!

作为前端工程师,你有没有遇到过这种情况:精心开发的页面,一上线就被用户吐槽卡顿、加载缓慢,甚至频繁崩溃。明明代码逻辑没问题,可性能就是上不去,这到底是哪里出了问题?别着急,今天就来分享5个超级实用...

周末复习前端js基础知识点总结一,记录完之后好复习(大佬勿喷)

一、深浅拷贝知识1、基本数据类型只有赋值没有拷贝2、数组和对象的赋值是浅拷贝3、结构赋值是深拷贝还是浅拷贝?二、实现深拷贝的几种常用方法方法1、通过json方法深拷贝方法2.基本的封装深拷贝的方法采用...

取消回复欢迎 发表评论: