热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从零实现一个高性能网络爬虫(一)网络请求分析及代码实现

摘要从零实现一个高性能网络爬虫系列教程第一篇,后续会有关于url去重、如何反爬虫、如何提高抓取效率、分布式爬虫系列文章。以我写的一个知乎爬虫为Demo讲解,github地址(https:gith

摘要

从零实现一个高性能网络爬虫系列教程第一篇,后续会有关于url去重、如何反爬虫、如何提高抓取效率、分布式爬虫系列文章。
以我写的一个知乎爬虫为Demo讲解,github地址 (https://github.com/wycm/zhihu-crawler) ,有兴趣的朋友可以star下。
网络请求的分析是写网络爬虫非常关键且重要的一个步骤。这篇文章以知乎网站为例,从网络请求分析到代码(java)实现。

目的

获取某个知乎用户的所有关注用户的个人资料

请求分析

  • 就目前的大部分网页来说,网页上能看到的数据大多都是直接在网站后台生成好数据(有的网页是在网站前端通过js代码处理后显示,如数据混淆、加密等)直接在前台显示。
  • 虽然很多网站采用了ajax异步加载,但是归根结底它还是一个http请求。只要能够分析出对应数据的请求来源,那么就很容易的拿到你想要的数据了。以下步骤讲解如何分析http请求。
  1. 以我的知乎账户为例,获取我的所有关注用户资料。首先打开我的关注列表,可以看到主面板就是我的关注用户列表,
    我一共关注233个用户,现在目的是就是要获取这233个用户的个人资料信息。打开F12->NetWork,勾选上Preserve log和Disable cache(如下图)。
  2. 下拉滚动条,点击下一页获取对应请求(在翻页的过程会有很多无关的请求),待页面加载完成后,在请求列表中右键->Save as HAR with content,这个文件是把当前请求(request)列表保存为
    json格式文本,保存后使用chrome打开这个文件,搜索(Ctrl+F)页面出现的关键字,要注意这里中文采用了unicode编码,我这里直接搜索5032(李博杰的关注者数,见下图)。这一步骤的目的是获取我们想要数据(关注用户的个人资料)的请求来源。
  3. 由步骤2搜索得出,关注用户的资料数据来自以下请求(如下图),url解码后为https://www.zhihu.com/api/v4/members/wo-yan-chen-mo/followees?include=data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics&offset=20&limit=20(url1),从这里可以看出关注列表的数据并不是从(url2)同步加载而来的,而是直接通过ajax异步请求url1来获得关注用户数据,然后通过js代码填充数据。这里要注意用红色矩形圈住的authorization request header,在代码实现的时候必须加上这个header。这个数据并不是动态改变的,通过步骤2的方式可以发现它是来自一个js文件。该步骤注意的是,我写该文章的时候是2017-04-27,随着时间推移,知乎可能会更新相关api接口的url,也就是说通过步骤2得出的url有可能并不是我上面的url1,但是具体分析的方法还是通用的。
  4. 多测试几次可以得出以上url1的参数含义如下
    参数名
    类型
    必填
    说明
     
    include
     
    String
     
     
    data[*]answer_count,articles_count
     
    需要返回的字段(这个值可以改根据需要增加一些字段)
     
    offset
     
    int
     
     
    0
     
    偏移量(通过调整这个值可以获取到一个用户的所有关注用户资料)
     
    limit
     
    int
     
     
    20
     
    返回用户数(最大20,超过20无效)
  5. 关于如何测试请求,我常用的以下三种方式
    • 原生chrome浏览器。可以做一些简单的GET请求测试,这种方式有很大的局限性,不能编辑http header。如果直接(未登录知乎)通过浏览器访问url1,会得到401的response code。因为它没有带上authorization request header。所以这种方式能测试一些简单且没有特殊request header的GET请求。
    • chrome插件Postman。一个很强大的http请求测试工具,可以直接编辑request header(包括COOKIEs)。如果可以FQ的话,强烈推荐。GET、POST、PUT等都是支持的,几乎可以发送任意类型的http请求,测试的url1如下图。通过修改它参数的值,来看服务器响应数据的变化来确定参数含义

       

    • intellij idea ultimate版自带的工具。打开方式 Tools->Test RESTful Web Service。也是可以直接编辑http header(包括COOKIEs)请求发送,GET、POST、PUT等请求方式也都是支持的。
  6. response是一段json格式的数据,中文是采用的unicode编码,解码后数据内容如下图

 

代码实现

  • 代码采用的Java HttpClient4.x,关于HttpClient4.x的使用我这里不过多讲解,要注意的是HttpClient4.x和3.x API有很大的差异。
 1 package com.cnblogs.wycm;
2
3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject;
5 import org.apache.http.client.methods.CloseableHttpResponse;
6 import org.apache.http.client.methods.HttpGet;
7 import org.apache.http.impl.client.CloseableHttpClient;
8 import org.apache.http.impl.client.HttpClients;
9 import org.apache.http.util.EntityUtils;
10
11 import java.io.IOException;
12
13 /**
14 * 获取wo-yan-chen-mo关注的所有知乎用户信息
15 * 只是把用户资料打印出来,没有具体解析(关于解析出详细数据可以采用正则表达式、json库、jsonpath等方式)
16 */
17 public class Demo {
18 public static void main(String[] args) throws IOException {
19 //创建http客户端
20 CloseableHttpClient httpClient = HttpClients.createDefault();
21
22 String url = "https://www.zhihu.com/api/v4/members/wo-yan-chen-mo/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=0&limit=20";
23
24 //创建http request(GET)
25 HttpGet request = new HttpGet(url);
26
27 //设置http request header
28 request.setHeader("authorization", "oauth c3cef7c66a1843f8b3a9e6a1e3160e20");
29 //执行http请求
30 CloseableHttpResponse respOnse= httpClient.execute(request);
31 //打印response
32 String respOnseStr= EntityUtils.toString(response.getEntity());
33 System.out.println(responseStr);
34
35 String nextPageUrl = getNextPageUrl(responseStr);
36 boolean isEnd = getIsEnd(responseStr);
37
38 while (!isEnd && nextPageUrl != null){
39 //创建http request(GET)
40 request = new HttpGet(nextPageUrl);
41
42 //设置http request header
43 request.setHeader("authorization", "oauth c3cef7c66a1843f8b3a9e6a1e3160e20");
44 respOnse= httpClient.execute(request);
45 //打印response
46 respOnseStr= EntityUtils.toString(response.getEntity());
47 System.out.println(responseStr);
48 nextPageUrl = getNextPageUrl(responseStr);
49 isEnd = getIsEnd(responseStr);
50 }
51 }
52
53 /**
54 * 获取next url
55 * @param responseStr
56 * @return
57 */
58 private static String getNextPageUrl(String responseStr){
59 JSONObject jsOnObject= (JSONObject) JSON.parse(responseStr);
60 jsOnObject= (JSONObject) jsonObject.get("paging");
61 return jsonObject.get("next").toString();
62 }
63
64 /**
65 * 获取is_end
66 * @param responseStr
67 * @return
68 */
69 private static boolean getIsEnd(String responseStr){
70 JSONObject jsOnObject= (JSONObject) JSON.parse(responseStr);
71 jsOnObject= (JSONObject) jsonObject.get("paging");
72 return (boolean) jsonObject.get("is_end");
73 }
74 }
  • maven依赖

 1   <dependency>
2 <groupId>org.apache.httpcomponentsgroupId>
3 <artifactId>httpclientartifactId>
4 <version>4.5version>
5 dependency>
6
7
8 <dependency>
9 <groupId>com.alibabagroupId>
10 <artifactId>fastjsonartifactId>
11 <version>1.2.31version>
12 dependency>

 


推荐阅读
  • publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • Requests库的基本使用方法
    本文介绍了Python中Requests库的基础用法,包括如何安装、GET和POST请求的实现、如何处理Cookies和Headers,以及如何解析JSON响应。相比urllib库,Requests库提供了更为简洁高效的接口来处理HTTP请求。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • 基于SSM框架的在线考试系统:随机组卷功能详解
    本文深入探讨了基于SSM(Spring, Spring MVC, MyBatis)框架构建的在线考试系统中,随机组卷功能的设计与实现方法。 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • 本文介绍了.hbs文件作为Ember.js项目中的视图层,类似于HTML文件的功能,并详细讲解了如何在Ember.js应用中集成Bootstrap框架及其相关组件的方法。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 本文详细介绍了在Windows系统中如何配置Nginx以实现高效的缓存加速功能,包括关键的配置文件设置和示例代码。 ... [详细]
  • 本文探讨了异步编程的发展历程,从最初的AJAX异步回调到现代的Promise、Generator+Co以及Async/Await等技术。文章详细分析了Promise的工作原理及其源码实现,帮助开发者更好地理解和使用这一重要工具。 ... [详细]
  • ASP.NET 进度条实现详解
    本文介绍了如何在ASP.NET中使用HTML和JavaScript创建一个动态更新的进度条,并通过Default.aspx页面进行展示。 ... [详细]
  • 本文探讨了如何在 Spring MVC 框架下,通过自定义注解和拦截器机制来实现细粒度的权限管理功能。 ... [详细]
  • 在测试软件或进行系统维护时,有时会遇到电脑蓝屏的情况,即便使用了沙盒环境也无法完全避免。本文将详细介绍常见的蓝屏错误代码及其解决方案,帮助用户快速定位并解决问题。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
author-avatar
耗子很傻爱钻洞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有