所用库

  • requests

  • xpath解析库

  • multiprocessing多进程

  • pymysql数据库操作库

实战背景

主要是爬取知乎热榜的问题及点赞数比较高的答案,通过requests请求库进行爬取,xpath进行解析,并将结果存储至mysql数据库中

爬取的url为:https://www.zhihu.com/hot

源码保存在我的github上:知乎热榜问题及答案数据获取

文章首发于个人网站:大圣的专属空间

代码实现

首先获取问题的标题以及其下属的答案的url地址,代码如下:

import requests
from lxml import etree
import time
import multiprocessing
import pymysqlheaders = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36','cookie': '***********'
}
url = 'https://www.zhihu.com/hot'
def get_question_num(url,headers):response = requests.get(url,headers=headers)text = response.texthtml = etree.HTML(text)reslut = html.xpath("//section[@class='HotItem']")# 获取问题的IDquestion_list = []for question in reslut:number = question.xpath(".//div[@class='HotItem-index']//text()")[0].strip()title = question.xpath(".//h2[@class='HotItem-title']/text()")[0].strip()href = question.xpath(".//div[@class='HotItem-content']/a/@href")[0].strip()question_num = href.split('/')[-1]question_list.append([question_num,title])# print(number,'\n',title,'\n',href)return question_list

其中,在请求头中加入了user-agent以及自己的cookie,如下图:

使用xpath进行页面解析,最终函数返回的结果为问题ID(即https://www.zhihu.com/question/359056618中的359056618,后面会将为什么是需要返回ID而不是整个url)以及问题的标题

获取到问题的标题以及问题的ID后,我们接下来需要获取问题下面的答案

进入问题答案详细页面,我们发现其问题是通过ajax请求进行加载的,如下:

我们发现其请求json数据的url为:

https://www.zhihu.com/api/v4/questions/359056618/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%2Cpaid_info_content%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=5&offset=5&platform=desktop&sort_by=default
# 变化量如:question_id:359056618, offset=5,10,15......

其变化的量主要有问题ID以及offset参数,其中offset控制每次加载的数量

因此我们开始实现获取答案的代码:

def data_json_request(question_id,question_title,headers):num = 0i = 1while True:json_url = 'https://www.zhihu.com/api/v4/questions/' + question_id + '/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%2Cpaid_info_content%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=5&offset={}&platform=desktop&sort_by=default'.format(num)data_json = requests.get(json_url,headers=headers)all_detail_data = data_json.json()['data']length_detail_data = len(all_detail_data)for one_detail_data in all_detail_data:question_title = question_titleanswer_author = one_detail_data['author']['name']author_introduce = one_detail_data['author']['headline']author_followers = one_detail_data['author']['follower_count']answer_vote_num = one_detail_data['voteup_count']answer_comment_num = one_detail_data['comment_count']updated_time = one_detail_data['updated_time']content = one_detail_data['content']# 保存数据至数据库db = pymysql.connect(host='localhost',user='root',password='123456',port=3306,db='spider_data')cursor = db.cursor()sql = 'INSERT INTO zhihu_hot_question(question_title,author_name,author_introduce,author_followers,answer_vote_num,answer_comment_num,updated_time,content) VALUES(%s,%s,%s,%s,%s,%s,%s,%s)'try:if int(answer_vote_num) >= 90:cursor.execute(sql,(question_title,answer_author,author_introduce,author_followers,answer_vote_num,answer_comment_num,updated_time,content))db.commit()print('数据写入成功!!!')else:print('点赞数太少,不保存至数据库!!!')except:print('数据写入失败!')db.rollback()# print(question_title,'\n',answer_author,'\n',author_introduce,'\n',author_followers,'\n',answer_vote_num,'\n',answer_comment_num# ,'\n',updated_time,'\n',content)num = i*5i = i+1if length_detail_data == 0:print('answaer_stop!!!!!')break

其中,我们设定当其答案全部加载完成后,跳出循环,即:

 if lenth_detail_data == 0:print('answaer_stop!!!!!')break

同时也将数据写入数据库的程序直接写入到获取答案的函数中,并且对于点赞数过少的不保存在数据库中(这里设置点赞数大于90进行保存)

最后编写main主函数,如下:

def main():question_id = get_question_num(url,headers)print(question_id)print('当前环境CPU核数是:{}核'.format(multiprocessing.cpu_count()))p = multiprocessing.Pool(4)for q_id in question_id:p.apply_async(data_json_request,args=(q_id[0],q_id[1],headers))p.close()p.join()

这里使用了多进程的方式进行数据的快速获取,最后运行整个程序,并统计最终耗时,如下:

if __name__ == "__main__":start = time.time()main()print('总耗时:%.5f秒'% float(time.time()-start))

最后发现爬取知乎热榜总共用了552s的时间,最终数据库中的保存数据如下:

这样我们就实现了知乎热榜问题及答案的数据获取

总结

  • 使用了最简单的requests请求库
  • 添加请求头的相关数据
  • 分析网页是否使用ajax请求
  • 爬取结果的数据保存(python操作mysql数据库)
  • 多进程的数据快速爬取

【知乎热榜爬虫】python爬取知乎热榜问题及答案相关推荐

  1. python爬虫知乎图片_python爬虫(爬取知乎答案图片)

    python爬虫(爬取知乎答案图片) 1.⾸先,你要在电脑⾥安装 python 的环境 我会提供2.7和3.6两个版本的代码,但是本⽂只以python3.6版本为例. 安装完成后,打开你电脑的终端(T ...

  2. [爬虫]python爬取B站日榜100名up主及其视频信息

    参观我们准备爬取的网页,注意:不要停留太久,内容太过丰富且有趣,等回过神来已经半天过去了 点此跳转 观察这个页面包含的信息,包括[标题][播放量][视频弹幕数量][up主姓名]- 常规操作,F12查看 ...

  3. python爬取知乎热榜了解时事

    python爬取知乎热榜了解时事 需求 ​ 知乎热榜是我们了解时事的一个重要途径,但是如果我们每天没有那么多时间来刷知乎,但是还是想要了解知乎热榜的话,我们该怎么办呢?在这里,我想到了通过知乎爬虫的手 ...

  4. python热搜排行功能_简单几行代码用Python爬取微博的热搜榜

    简单几行代码用Python爬取微博的热搜榜 想要实时的看微博热搜 但是又不想去微博网站看!怎么办呢?其实很简单! 我们学了这个requests_html 这个库之后 就更加的简单了! 小编只用了短短的 ...

  5. python 知乎美女_知乎大神用Python爬取高颜值美女(爬虫+人脸检测+颜值检测)

    原标题:知乎大神用Python爬取高颜值美女(爬虫+人脸检测+颜值检测) 1 数据源 知乎话题『美女』下所有问题中回答所出现的图片 2 抓取工具 Python 3,并使用第三方库 Requests.l ...

  6. Python爬取知乎“神回复”,笑得根本停不下来(附代码)

    来源:Python与数据分析 本文约4600字,建议阅读10+分钟. 本文介绍如何爬取知乎的神回复,为你揭晓其背后的原理. 知乎上经常会有很多令人忍俊不禁的神回复,初看之下拍案叫绝,细思之下更是回味无 ...

  7. 用Python爬取知乎上关于程序员的神回复

    数据科学俱乐部 中国数据科学家社区 ♚ 作者:强哥,曾供职于摩根士丹利和eBay. 爬取知乎神回复很简单,这篇文章我们就来揭晓一下背后的原理. 知乎神回复都有些什么特点呢?我们先来观察一下 大家看出什 ...

  8. python爬取知乎回答并进行舆情分析:爬取数据部分

    python爬取知乎回答并进行舆情分析:爬取数据部分 背景 Ajax原理介绍 Request URL分析 json报文结构分析 代码 参考链接 背景 近期导师让我从社交媒体平台(包括微博.知乎.贴吧等 ...

  9. 如何用python爬取数据_如何使用python爬取知乎数据并做简单分析

    原标题:如何使用python爬取知乎数据并做简单分析 一.使用的技术栈: 爬虫:python27 +requests+json+bs4+time 分析工具: ELK套件 开发工具:pycharm 数据 ...

  10. python爬取知乎回答并进行舆情分析:舆情分析部分

    python爬取知乎回答并进行舆情分析:舆情分析部分 背景 生成词云 文本预处理(使用停用词.自定义分词) 统计词频 生成词云 折线图 统计每日回答数 生成折线图 展望 背景 在上一节中,利用爬虫爬取 ...

最新文章

  1. QT关于使用MSVC之后,之前用MGW编译代码,用这个GDB调试器出现error
  2. 三种权重的初始化方法
  3. Python:23种Pandas核心操作
  4. 怪物猎人服务器维护时间,怪物猎人云服务器
  5. 自定义注解与validation结合使用案例
  6. jquery form java_springmvc利用jquery.form插件异步上传文件示例
  7. 数据结构与算法 —— 链表linked list(05)
  8. 扩展空间_实用!Win10开启SMB共享的方法,给GPD MicroPc扩展更多存储空间
  9. mac OS X下终端使用tree命令列目录
  10. 判断浏览器内核是否是IE8及其以下
  11. JAVA 图片格式检查方法
  12. 新猿木子李:0基础学python培训教程 Python操作Redis之集合类型
  13. Deformable Convolutional Networks论文翻译——中文版
  14. 一个屌丝程序猿的人生(一百一十八)
  15. Codeforces Round #772 (Div. 2) CF1635ABCDEF
  16. Leetcode-至多包含两个不同字符的最长子串
  17. RAID5数据应该如何恢复
  18. 也谈智能手机游戏开发中的分辨率自适应问题
  19. QMdiSubWindow
  20. Watir vs. SilkTest

热门文章

  1. 高分子化学靠自己的记忆(更新中)
  2. 诚之和:Pytorch 统计模型参数量的操作 param.numel()
  3. 面试官:Redis中集合数据类型的内部实现方式是什么?
  4. 实战 | SpringBoot微信点餐系统(附源码)
  5. 活性氧L-Buthionine-(S,R)-Sulfoximine,CAS No. 83730-53-4
  6. 应聘信计算机英语怎么说,英文应聘信怎么写
  7. 第一次Scrum冲刺-Life In CCSU
  8. 同步请求和异步请求(利用axios)
  9. axios发送GET请求(Content-Type)后端如何接收。
  10. SuperMap iMobile 8C(2017) for Android 室内导航技术文档