{"id":13488695,"url":"https://github.com/moranzcw/Zhihu-Spider","last_synced_at":"2025-03-28T01:37:21.064Z","repository":{"id":108253272,"uuid":"91180996","full_name":"moranzcw/Zhihu-Spider","owner":"moranzcw","description":"一个获取知乎用户主页信息的多线程Python爬虫程序。","archived":false,"fork":false,"pushed_at":"2019-01-21T20:26:46.000Z","size":54787,"stargazers_count":138,"open_issues_count":4,"forks_count":50,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-31T00:40:09.380Z","etag":null,"topics":["crawler","jupyter-notebook","matplotlib","python","requests","zhihu-spider"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moranzcw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-05-13T14:46:14.000Z","updated_at":"2024-10-29T18:31:58.000Z","dependencies_parsed_at":"2023-05-09T15:31:22.375Z","dependency_job_id":null,"html_url":"https://github.com/moranzcw/Zhihu-Spider","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moranzcw%2FZhihu-Spider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moranzcw%2FZhihu-Spider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moranzcw%2FZhihu-Spider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moranzcw%2FZhihu-Spider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moranzcw","download_url":"https://codeload.github.com/moranzcw/Zhihu-Spider/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245952912,"owners_count":20699558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crawler","jupyter-notebook","matplotlib","python","requests","zhihu-spider"],"created_at":"2024-07-31T18:01:20.220Z","updated_at":"2025-03-28T01:37:21.058Z","avatar_url":"https://github.com/moranzcw.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Zhihu-Spider\n\n一个获取知乎用户主页信息的多线程Python爬虫程序。\n\n简介：\n\n* 使用[Requests](http://www.python-requests.org/en/master/)模拟HTTP请求/响应，[Beautiful Soup 4](https://www.crummy.com/software/BeautifulSoup/)提取页面信息。\n* 使用Python内置的Thread多线程和IP代理提升爬取速度，并绕过知乎的反爬虫机制。\n* 使用Python内置的query作为消息队列。\n* 用csv文件存储数据。\n\n## 环境依赖\n\n* beautifulsoup4\n* requests\n\n## 使用方法\n\n在项目路径下输入以安装需要的模块：\n\n```shell\n$ pip install -r requirments.txt\n```\n\n打开proxy.py文件，在\"\"处填写代理隧道验证信息：\n\n```python\n# 代理隧道验证信息\nproxyUser = \"\"\nproxyPass = \"\"\n```\n\n（笔者使用一个IP代理隧道，若需要使用普通IP代理，则需要改写getproxies函数，关于代理的细节在后文中详述。）\n\n运行：\n\n```shell\n$ python spider/run.py\n```\n\n## 数据\n\n运行爬虫一段时间后，将会在项目目录下的datafile文件夹中找到存储数据的csv文件。\n\n![](./image/datafilelist.png)\n\n每个csv文件100MB，以方便数据分析，同时降低文件意外损坏带来的损失。\n\n数据格式为典型的表格：\n\n![](./image/datafile.png)\n\n第一行为表头，表格一共三列：\n\n1. **第一列为用户的url token**，即用户主页url中的id，如用户vczh的主页链接：https://www.zhihu.com/people/excited-vczh ，那么vczh的token就是excited-vczh，这个token具有唯一性。\n\n2. **第二列为对应用户的数据**，数据是json格式的，因为知乎在页面中是以json来传送用户信息的，所以就直接存储了这个json，Python内置json读写函数，非常方便数据分析。\n\n   以下是整理格式后，用户vczh的数据:\n\n   ```json\n   {\n       \"isFollowed\":false,\n       \"educations\":[\n           {\n               \"major\":{\n                   \"url\":\"http://www.zhihu.com/api/v4/topics/19590324\",\n                   \"avatarUrl\":\"https://pic1.zhimg.com/e82bab09c_is.jpg\",\n                   \"name\":\"软件学院\",\n                   \"introduction\":\"\",\n                   \"type\":\"topic\",\n                   \"excerpt\":\"\",\n                   \"id\":\"19590324\"\n               },\n               \"school\":{\n                   \"url\":\"http://www.zhihu.com/api/v4/topics/19599737\",\n                   \"avatarUrl\":\"https://pic2.zhimg.com/4d0d193a9_is.jpg\",\n                   \"name\":\"华南理工大学（SCUT）\",\n                   \"introduction\":\"华南理工大学（South China University of Technology）（原华南工学院，1952年建立）：教育部直属的重点大学，涵盖理、工、管、经、文、法等多学科，先后成为“211工程”和“985工程”院校，被誉为中国“南方工科大学的一面旗帜”，“工程师的摇篮”，“企业家的摇篮”。校园分为两个校区，北校区位于广州市天河区五山高校区，南校区位于广州市番禺区广州大学城内。学校占地面积4417亩(其中南校区1677亩)。北校区湖光山色交相辉映，绿树繁花香飘四季，民族式建筑与现代化楼群错落有致，环境优美清新，文化底蕴深厚，是教育部命名的“文明校园”；南校区是一个环境优美、设施先进、管理完善、制度创新的现代化校园，是莘莘学子求学的理想之地。\",\n                   \"type\":\"topic\",\n                   \"excerpt\":\"华南理工大学（South China University of Technology）（原华南工学院，1952年建立）：教育部直属的重点大学，涵盖理、工、管、经、文、法等多学科，先后成为“211工程”和“985工程”院校，被誉为中国“南方工科大学的一面旗帜”，“工程师的摇篮”，“企业家的摇篮”。校园分为两个校区，北校区位于广州市天河区五山高校区，南校区位于广州市番禺区广州大学城内。学校占地面积4417亩(其中南校区1677亩)。北校区湖光山色交相辉…\",\n                   \"id\":\"19599737\"\n               }\n           }\n       ],\n       \"followingCount\":2263,\n       \"voteFromCount\":0,\n       \"userType\":\"people\",\n       \"showSinaWeibo\":false,\n       \"pinsCount\":0,\n       \"isFollowing\":false,\n       \"markedAnswersText\":\"编辑推荐\",\n       \"isPrivacyProtected\":false,\n       \"accountStatus\":[\n\n       ],\n       \"isForceRenamed\":false,\n       \"id\":\"0970f947b898ecc0ec035f9126dd4e08\",\n       \"favoriteCount\":1,\n       \"voteupCount\":1388515,\n       \"commercialQuestionCount\":0,\n       \"isBlocking\":false,\n       \"followingColumnsCount\":73,\n       \"headline\":\"专业造轮子，拉黑抢前排。gaclib.net\",\n       \"urlToken\":\"excited-vczh\",\n       \"participatedLiveCount\":6,\n       \"followingFavlistsCount\":20,\n       \"isAdvertiser\":false,\n       \"isBindSina\":true,\n       \"favoritedCount\":236566,\n       \"isOrg\":false,\n       \"followerCount\":583782,\n       \"employments\":[\n           {\n               \"company\":{\n                   \"url\":\"http://www.zhihu.com/api/v4/topics/19557307\",\n                   \"avatarUrl\":\"https://pic3.zhimg.com/v2-d3a9ee5ba3a2fe711087787c6169dcca_is.jpg\",\n                   \"name\":\"Microsoft Office\",\n                   \"introduction\":\"Microsoft Office 是一套由微软开发的办公软件。\",\n                   \"type\":\"topic\",\n                   \"excerpt\":\"Microsoft Office 是一套由微软开发的办公软件。\",\n                   \"id\":\"19557307\"\n               },\n               \"job\":{\n                   \"url\":\"http://www.zhihu.com/api/v4/topics/19578588\",\n                   \"avatarUrl\":\"https://pic1.zhimg.com/e82bab09c_is.jpg\",\n                   \"name\":\"Developer\",\n                   \"introduction\":\"\",\n                   \"type\":\"topic\",\n                   \"excerpt\":\"\",\n                   \"id\":\"19578588\"\n               }\n           }\n       ],\n       \"type\":\"people\",\n       \"avatarHue\":\"\",\n       \"avatarUrlTemplate\":\"https://pic1.zhimg.com/3a6c25ac3864540e80cdef9bc2a73900_{size}.jpg\",\n       \"followingTopicCount\":34,\n       \"description\":\"长期开发跨三大PC平台的GUI库\u003cbr\u003e\u003ca href=\"https://link.zhihu.com/?target=http%3A//www.gaclib.net\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003e\u003cspan class=\"invisible\"\u003ehttp://www.\u003c/span\u003e\u003cspan class=\"visible\"\u003egaclib.net\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003ci class=\"icon-external\"\u003e\u003c/i\u003e\u003c/a\u003e，讨论QQ群：231200072（不闲聊）\u003cbr\u003e不再更新的技术博客：\u003ca href=\"https://link.zhihu.com/?target=http%3A//www.cppblog.com/vczh\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003e\u003cspan class=\"invisible\"\u003ehttp://www.\u003c/span\u003e\u003cspan class=\"visible\"\u003ecppblog.com/vczh\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003ci class=\"icon-external\"\u003e\u003c/i\u003e\u003c/a\u003e\",\n       \"business\":{\n           \"url\":\"http://www.zhihu.com/api/v4/topics/19619368\",\n           \"avatarUrl\":\"https://pic1.zhimg.com/e82bab09c_is.jpg\",\n           \"name\":\"计算机软件\",\n           \"introduction\":\"徼\",\n           \"type\":\"topic\",\n           \"excerpt\":\"徼\",\n           \"id\":\"19619368\"\n       },\n       \"avatarUrl\":\"https://pic1.zhimg.com/3a6c25ac3864540e80cdef9bc2a73900_is.jpg\",\n       \"columnsCount\":5,\n       \"hostedLiveCount\":0,\n       \"isActive\":1,\n       \"thankToCount\":0,\n       \"mutualFolloweesCount\":0,\n       \"markedAnswersCount\":4,\n       \"coverUrl\":\"https://pic1.zhimg.com/v2-67b965aa94a92ed49b1a4205145b5cf4_b.jpg\",\n       \"thankFromCount\":0,\n       \"voteToCount\":0,\n       \"isBlocked\":false,\n       \"answerCount\":16163,\n       \"allowMessage\":false,\n       \"articlesCount\":66,\n       \"name\":\"vczh\",\n       \"questionCount\":487,\n       \"locations\":[\n           {\n               \"url\":\"http://www.zhihu.com/api/v4/topics/19583552\",\n               \"avatarUrl\":\"https://pic4.zhimg.com/161f6ece791a4950ded3278fb74a2f9b_is.jpg\",\n               \"name\":\"西雅图（Seattle）\",\n               \"introduction\":\"西雅图是美国西北部最大的城市。多家高科技公司的总部（Microsoft, Amazon，Boeing 等等）坐落于此。\",\n               \"type\":\"topic\",\n               \"excerpt\":\"西雅图是美国西北部最大的城市。多家高科技公司的总部（Microsoft, Amazon，Boeing 等等）坐落于此。\",\n               \"id\":\"19583552\"\n           }\n       ],\n       \"badge\":[\n\n       ],\n       \"url\":\"http://www.zhihu.com/api/v4/people/0970f947b898ecc0ec035f9126dd4e08\",\n       \"messageThreadToken\":\"4874924000\",\n       \"logsCount\":2365,\n       \"followingQuestionCount\":26892,\n       \"thankedCount\":176110,\n       \"gender\":1\n   }\n   ```\n\n   可以看到，用户vczh的大部分基本信息都被包含了。\n\n3. **第三列保存每个用户的关注用户列表**，每个用户只保存20个，此列不用作为数据，只作为爬虫中断后恢复现场和任务队列的用处，分析数据时可以忽略。\n\n## 程序介绍\n#### 程序文件结构\n程序文件结构如下：\n\n![](./image/file.png)\n\n* spider文件夹：爬虫程序文件\n  * proxy.py: 包含getproxy()函数，用于获取代理服务器的IP地址和端口，调用一次返回一个代理IP。\n  * crawl.py: 包含Crawl类，实现用户页面的获取和用户json信息的提取。\n  * datafile.py: 包含DataFile类，实现数据文件的管理和存取。\n  * run.py: 程序执行的主要流程，实现了多线程爬虫，其中一个Master线程管理已爬取列表和生成待爬取任务，并响应Worker线程返回的信息；若干Worker线程，数量可设置，用于爬取用户信息并存入数据文件中，同时向Master线程返回一个状态信息。\n* datafile文件夹：存储数据文件\n\n#### 程序流程\n\n程序流程如下：\n\n![](./image/flow.png)\n\n这个爬虫的策略是，选择一个用户作为起始点，获取他的关注列表，加入到任务队列中，作为之后将要爬取的用户，继续获取这些用户的关注列表，去重再加入任务队列，如此循环。把知乎的用户关系看作一个图的话，这个策略类似于广度优先搜索。\n\n至于为什么使用关注列表而不是被关注列表，因为通常每个用户关注的用户都是有效用户，而被关注列表中往往存在三零用户，脚本注册的伪用户等，这类用户通常不被其他用户关注。所以这种策略能高效地筛选出知乎的有效用户。\n\n#### 代理\n\n知乎拥有一定的反爬虫机制。在此案例中，知乎的用户页面不需要登录就能查看，所以需要解决的问题就是IP封锁。笔者简单测试，对于一个IP，每秒一次请求，大约5分钟后就会要求输入验证码，可以说非常严格，所以使用IP代理服务来解决IP封锁的问题。\n\n一般来说，我们有两种解决方案，一种是自己搜集免费代理，建立一个IP代理池，第二种是直接使用付费代理服务。无论哪种，我们的获取代理IP并爬取目标网站的流程大致是这样：\n\n![](./image/proxy.png)\n\n通过IP代理服务请求一个IP，再使用这个IP代理服务器转发请求，获取页面。\n\n笔者使用的IP代理服务略有区别，是一种IP代理隧道，流程大致是这样的：\n\n![](./image/proxytunnel.png)\n\n对于爬虫来说，就省略了一个获取IP的步骤，只需要直接将请求发送到指定的IP代理服务就可以了。\n\n如果需要使用使用上一种通用的IP代理模式，那么只需要再proxy.py中重写getproxies函数就可以了。\n\n#### 用户信息获取\n\n通常一个请求/响应不能加载一个完整页面，所以需要一组请求/响应来完成html文本，JavaScript代码，图片/音频等资源文件的加载。不过这个爬虫案例中，我们在第一次请求/响应中获取的html文档就包含我们需要的所有信息。\n\n以用户vczh为例，其主页为 https://www.zhihu.com/people/excited-vczh ，这个页面下还有anwsers，asks，posts等标签页，我们直接访问following（关注列表）标签页，即 https://www.zhihu.com/people/excited-vczh/following ， 这样一次请求/响应即可同时获得用户信息和用户关注列表。\n\n打开chrome调试工具，查看第一次请求/响应的详细内容：\n\n![](./image/request.png)\n\n得到html文本后，在html接近末尾的一个div标签中，有一个data-state属性，它用json存储了信息，我们需要的用户信息和用户关注列表都在其中：\n\n![](./image/datastate.png)\n\n#### 数据存储\n\n数据采用csv文件存储，对于pandas等数据分析工具，csv格式非常方便。\n\n考虑到文件意外损坏的可能性，分多个文件存储，每个文件100MB。\n\n由于程序使用了多线程，所以在存取数据时保证了线程安全。\n\n#### 并发\n程序使用多线程来解决网络IO阻塞导致CPU空闲的问题。\n\n由于Python原生解释器的GIL锁，Python的多线程只是在一个CPU上切换运行，而不是在多个CPU上并行运行，所以使用场景有一些限制。换句话说，对于一颗四核心的CPU，一个Python程序实例最高只有25%的占用率。\n\n![](./image/run.jpg)\n\n不过对于此爬虫案例，GIL锁并不是瓶颈，笔者测试，此程序在使用某个付费代理服务时，在200线程的情况下，能保持100请求/s的并发，CPU占用率约在17%-22%（笔记本四核i7），带宽占用不足1MB/s。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoranzcw%2FZhihu-Spider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoranzcw%2FZhihu-Spider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoranzcw%2FZhihu-Spider/lists"}