##目的:对网易新闻app进行自媒体号进行数据采集


工具: fiddler4,IDEA


前置技能点:

  1. Java基础,基本语法,文件操作,Date类应用,maven的配置等
  2. fiddler抓包
  3. 生产者 消费者模型的Java实现
  4. Java httpclient包的基本运用
  5. JSONObject类的运用

##流程:
###1. 用fiddler对网易新闻app进行抓包研究(此处最为复杂,又难以归纳出通用的法则)
下面给出几个关键的url

简介获取网址: http://c.m.163.com/nc/subscribe/abstract/自媒体id.html
以T1436178714849这个自媒体id为例
以get方式对该url进行请求,获取到下列返回数据,经过观察,我们可以发现该串json数据中的desc键描述了该自媒体的简介信息

{"abstractList": [{"topicid": "051187K4","ename": "T1437980175117","img": "http://dingyue.nosdn.127.net/CPyl06T14=6lx2V=Gy8BzwbDVnng40gvC2mkcTZmgYTvn1488900231940.jpg","hasIcon": true,"tname": "智观察","subnum": "9164","topic_icons": "http://dingyue.nosdn.127.net/CPyl06T14=6lx2V=Gy8BzwbDVnng40gvC2mkcTZmgYTvn1488900231940.jpg","tid": "T1437980175117"},{"topicid": "0511838M","ename": "T1426650607511","img": "http://img1.ph.126.net/0JLWi3-AFGkp_IJ39FzhTQ==/6619378857584634163.jpg","hasIcon": true,"tname": "芯智讯","subnum": "1万","topic_icons": "http://img1.ph.126.net/0JLWi3-AFGkp_IJ39FzhTQ==/6619378857584634163.jpg","tid": "T1426650607511"},{"topicid": "0511831Q","ename": "T1425885645380","img": "http://img2.ph.126.net/NiwTiVUjwMyfEbGGNuiAyA==/6630195852978107453.jpg","hasIcon": true,"tname": "华强北在线","subnum": "1.5万","topic_icons": "http://img2.ph.126.net/NiwTiVUjwMyfEbGGNuiAyA==/6630195852978107453.jpg","tid": "T1425885645380"}],"abstractType": "similar","desc": "3D打印在线(www.3d2013.com)是由世界3D打印技术产业联盟与中国3D打印技术产业联盟联袂主办的3D打印行业首家在线交易平台,是3D打印行业权威的信息资讯门户。"
}

同理对名称,别名等信息获取网址: http://c.m.163.com/nc/subscribe/v2/topic/自媒体id.html
利用get方式进行请求,获取下列json数据,可以通过该数据获取到自媒体的名称(tname),粉丝数(subnum),别名(alias)等信息

{"tab_list": [{"tab_type": "all","tab_name": "文章"},{"tab_type": "abstract","tab_name": "简介"}],"subscribe_info": {"template": "normal1","ename": "T1436178714849","passport": "dDmPEbeEDNJpDRGAlWMCEmWlYJxG7i/ExMsC/IX1t2E=","hasCover": false,"topic_background": "http://img2.cache.netease.com/m/newsapp/reading/cover1/C1374477668016.jpg","certificationUrl": "http://mp.163.com/mobile/auth.html#/index","hasIcon": true,"alias": "www.3d2013.com","tname": "3D打印在线","topic_icons": "http://dingyue.nosdn.127.net/Tg1kLhUOqzABq3i6HE7gyPJkHSeLxyRjDjqq43hrEFZWS.jpg","subnum": "8746","cid": "C1374477668016"}
}

通过app的搜索功能来获取自媒体的id
url:http://c.m.163.com/nc/topicset/v5/searchByPage/android/" + 从搜索结果的第几项开始+ "-20.html
利用post方式进行请求获取(注意构建header和RequestBody)

获取结果

2.利用maven导入相关包

主要是JSONObject依赖,httpclient依赖

<dependencies><!-- jsoup解析依赖包 --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.7.3</version></dependency><!-- JSONObject依赖--><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.1</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.5</version></dependency><dependency><groupId>net.sf.ezmorph</groupId><artifactId>ezmorph</artifactId><version>1.0.3</version></dependency><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency><!-- httpclient依赖 --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.6</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version></dependency></dependencies>

3. 根据爬取流程确定架构

我们爬取一个自媒体信息的过程,首先是通过构建搜索url来获取一系列的自媒体的id,然后才通过其id与简介url和名称url爬取该自媒体的简介信息与名称信息
这很自然的构成了一个生产者-消费者模型
所以一只爬虫需要两类线程,一类生产者(负责爬取自媒体id),一类消费者(负责通过id补全自媒体其他信息)

实现代码

生产者

package thread;import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import util.Filter;
import util.URLUtil;
import vo.PageVo;import java.util.List;
import java.util.concurrent.BlockingQueue;/*** 通过网易app搜索引擎获取自媒体名单*/
public class ThirdThread implements Runnable
{BlockingQueue<PageVo> queue;Filter filter;//TODO 测试时设置上限static int MaxNum = 0;final String filePath = "D:/wangyiApp/";public ThirdThread(BlockingQueue<PageVo> queue){this.queue = queue;filter = new Filter();}@Overridepublic void run(){List<String> stringList = URLUtil.getGB2312List();//对搜索关键词进行遍历for (String s : stringList){int num = 0;String data = null;//对单个关键词的结果进行遍历while (true){String httpUrl = "http://c.m.163.com/nc/topicset/v5/searchByPage/android/" + num + "-20.html";num += 20;try{data = URLUtil.doPost(httpUrl, "keyWord=" + URLUtil.getEncodedBase64(s));JSONObject jsonObject = JSONObject.fromObject(data);//获取其他公众号网址JSONArray jsonArray = jsonObject.getJSONArray("result");//当结果页结束时,换下一个搜索词if (jsonArray.size() == 0){break;}for (int i = 0; i < jsonArray.size(); i++){System.out.println("线程" + Thread.currentThread().getName() + "容量" + queue.remainingCapacity());//当队列剩余容量小于2时,丢弃该公众号网页if (queue.remainingCapacity() < 2){}PageVo vo = new PageVo();// 遍历 jsonarray 数组,把每一个对象转成 json 对象JSONObject job = jsonArray.getJSONObject(i);// 得到自媒体idString ID = job.getString("tid");vo.setId(ID);/*** 对网址去重*/if (filter.Contain(ID)){System.out.println("爬取到一条重复记录");continue;}vo.setUrl(ID);queue.put(vo);System.out.println(ID);}} catch (Exception e){e.printStackTrace();}}}}}

消费者

package thread;import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import util.FileUtil;
import util.Filter;
import util.URLUtil;
import vo.PageVo;import java.util.concurrent.BlockingQueue;/*** 一号线程,爬取对应自媒体的简介,名称等信息** 简介获取网址:  http://c.m.163.com/nc/subscribe/abstract/自媒体id.html* 名称,别名等信息获取网址:  http://c.m.163.com/nc/subscribe/v2/topic/自媒体id.html*/
public class FirstThread implements Runnable
{BlockingQueue<PageVo> queue;Filter filter;//TODO 测试时设置上限static int MaxNum = 0;final String filePath="D:/wangyiApp/";public FirstThread(BlockingQueue<PageVo> queue){this.queue = queue;filter = new Filter();}@Overridepublic void run(){while (true){//TODO 测试用synchronized (this){MaxNum++;}try{PageVo pageVo = queue.take();//构建简介获取网址String  descUrl="http://c.m.163.com/nc/subscribe/abstract/"+pageVo.getId()+".html";JSONObject jsonObject = JSONObject.fromObject(URLUtil.doGet(descUrl));String desc = jsonObject.getString("desc");pageVo.setDescription(desc);//构建名称等信息获取网址String msgUrl="http://c.m.163.com/nc/subscribe/v2/topic/"+pageVo.getId()+".html";JSONObject jsonObject2 = JSONObject.fromObject(URLUtil.doGet(msgUrl));JSONObject msg=jsonObject2.getJSONObject("subscribe_info");pageVo.setAlias(msg.getString("alias"));pageVo.setAvatarsUrl(msg.getString("topic_icons"));pageVo.setName(msg.getString("tname"));//将subnum中的xx万转为数字String tmp=msg.getString("subnum");if (tmp.length()>1&&tmp.substring(tmp.length()-1).equals("万")){float tmp2= Float.parseFloat(tmp.substring(0,tmp.length()-1));pageVo.setFanNum(String.valueOf((int) (tmp2*10000)));}pageVo.setUrl(msgUrl);//标注为网易pageVo.setSite("netease");//储存FileUtil.save(pageVo,filePath);//                //获取其他公众号网址
//                JSONArray jsonArray = jsonObject.getJSONArray("abstractList");
//
//                for (int i = 0; i < jsonArray.size(); i++)
//                {
//                    System.out.println("线程"+Thread.currentThread().getName()+"容量"+queue.remainingCapacity());
//                    //当队列剩余容量小于2时,丢弃该公众号网页
//                    if (queue.remainingCapacity() < 2)
//                    {
//
//                    }
//                    PageVo vo = new PageVo();
//
//                    // 遍历 jsonarray 数组,把每一个对象转成 json 对象
//                    JSONObject job = jsonArray.getJSONObject(i);
//                    // 得到 每个对象中的属性值
//                    String ID = job.getString("ename");
//                    vo.setId(ID);
//
//
//                    /**
//                     * 对网址去重
//                     */
//                    if (filter.Contain(ID))
//                    {
//                        System.out.println("爬取到一条重复");
//                        continue;
//                    }
//                    vo.setUrl(ID);
//                    queue.put(vo);
//
//                    System.out.println();
//                }}catch (Exception e){}}}
}

可能遇到的问题:

####NO1.fiddler抓不到包,真心玄学问题,试过各种解决方法包括利用wireshark从底层抓包,都没有解决,在这一步卡了快一天,最后发现重装了一下网易新闻app。。。。就好了,好了,了
####No2.用被爬取app的搜索引擎,然后就想到了利用常用的汉字作为搜索关键词,然而,去那去找这些常用的汉字表呢?此时很自然的就想到了gb2312字符集。所以此时需要遍历gb2312字符集

//对gb2312字符集遍历try{//遍历gb2312汉字编码分区for (int i=0xB0;i<0xF7;i++){//遍历每个分区中的汉字for (int j=0xA1;j<0xFF;j++){byte[] bytes=new byte[2];bytes[0]= (byte) i;bytes[1]= (byte) j;short tmp= (short) (i+j);String s = new String(bytes, "gb2312");System.out.println(s);}}} catch (UnsupportedEncodingException e){e.printStackTrace();}

No3.网易app的搜索汉字使用base64编码的(常识),但一时想不到可能就会很迷

/***  通过jdk8的util类中的Base64类实现 base64编码* @param plainText* @return*/public static String getEncodedBase64(String plainText){String encoded = null;try{byte[] bytes = plainText.getBytes("UTF-8");encoded = Base64.getEncoder().encodeToString(bytes);} catch (UnsupportedEncodingException e){e.printStackTrace();}return encoded;}

####No4. set的线程安全问题,因为爬虫肯定涉及到去重问题,在数据量不大时,常直接采用set去重,然而set并不是线程安全滴,在爬虫这种典型的多线程应用中,肯定是不行的,此时可以通过利用synchronizedSet使set线程安全(private static Set set= Collections.synchronizedSet(new HashSet());),当然,也可以自己通过synchronized实现


###思考:app爬虫和一般的网络爬虫的区别
app的各个网址(节点)分布就类似于计网中的星型拓扑结构,各个页面间一般没用能直接跳转到其他页面的url(或者是只有同一类的页面间能相互跳转),所以普通页面就相当于星型结构中的周围节点。而中心节点则是app的搜索url,只有通过app的搜索功能才能找到这些周围节点

而一般的网络爬虫,则是网状模型,一般来说,重任意节点都能很容易的遍历整个网络

网易新闻app自媒体号信息爬取相关推荐

  1. python爬网易新闻_Python爬虫实战教程:爬取网易新闻

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Amauri PS:如有需要Python学习资料的小伙伴可以加点击 ...

  2. python爬网易新闻_Python爬虫实战教程:爬取网易新闻;爬虫精选 高手技巧

    Python爬虫实战教程:爬取网易新闻:爬虫精选 高手技巧 发布时间:2020-02-21 17:42:43 前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有, ...

  3. python3 爬虫实战之爬取网易新闻APP端

    (一)使用工具 这里使用了火狐浏览器的user-agent插件,不懂的可以点这里火狐插件使用 (二)爬虫操作步骤: 百度 网易新闻并选择 步骤一: 步骤二: 步骤三: 步骤四: 最后一步: 注意点: ...

  4. 仿网易新闻APP(四)——标题栏之本市天气(百度定位与车联网之天气查询)

    废话不多说,上图: 下面用到的知识有,百度定位及车联网API的使用,当然车联网API看起来高大上,其实我们这里只用来获取车联网中的天气查询功能.其他的功能还有渐变动画及缩放动画,以及定时更新天气及定位 ...

  5. python微信爬取教程_python爬虫_微信公众号推送信息爬取的实例

    问题描述 利用搜狗的微信搜索抓取指定公众号的最新一条推送,并保存相应的网页至本地. 注意点 搜狗微信获取的地址为临时链接,具有时效性. 公众号为动态网页(JavaScript渲染),使用request ...

  6. python微信公众号推送_python爬虫_微信公众号推送信息爬取的实例

    问题描述 利用搜狗的微信搜索抓取指定公众号的最新一条推送,并保存相应的网页至本地. 注意点 搜狗微信获取的地址为临时链接,具有时效性. 公众号为动态网页(JavaScript渲染),使用request ...

  7. python爬虫公众号_python爬虫_微信公众号推送信息爬取的实例

    问题描述 利用搜狗的微信搜索抓取指定公众号的最新一条推送,并保存相应的网页至本地. 注意点 搜狗微信获取的地址为临时链接,具有时效性. 公众号为动态网页(JavaScript渲染),使用request ...

  8. 基于搜狗接口的微信公众号及其信息爬取

    1.思路 经测试,搜狗搜索提供的微信公众号的接口是理所当然爬取多了会被封ip等方式重点照顾.这只是做一个公众号及其链接的爬取,公众号的内容爬取及制定内容的爬取都是一个路子.搞懂了一个其他的就都差不多了 ...

  9. 微博点赞数等信息和公众号点赞数等信息爬取

    一:微博 因为GitHub页面中已有非常详细的描述,这里只贴出地址和运行结果. 地址: https://github.com/dataabc/weiboSpider 运行结果:(获取点赞数,转发数,评 ...

最新文章

  1. java jtextpane插入图片_java中怎么在JTextArea中添加图片?
  2. linux gcc 静态编译,GCC 程序编译的静态链接和动态链接
  3. 实现Operations Manager 2012 R2单一部署
  4. ssrf漏洞内网渗透_渗透技巧之SSRF
  5. pb调用键盘钩子的例子_搞不动Vue3.0的源码,先做个API调用师也行(新人踩坑初试)...
  6. 让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求--转载
  7. python工作技巧_4个基本的 Python 技巧让你的工作流程自动化
  8. Logback配置一(按时间归档)
  9. NUC1421 时间日期格式转换【日期计算】
  10. sm缩写代表什么意思_PE给水管常见的字母缩写都代表什么?
  11. 深度学习人工智能中编写程序
  12. 智学网登录不了java_智学网登录不上怎么办?智学网app无法登录解决方法介绍...
  13. linux怎样补丁更新光盘,给Ubuntu也做个“SP3”补丁包光盘
  14. 完美世界:你病了,要么离职,要么996,要么小黑屋三选一
  15. 复杂领域的Cynefin模型和Stacey模型
  16. BFA“瑞云科技”大视频讲堂第五期“从好莱坞电影融资模式到中国电影的国际化”...
  17. QQ服务器维护一般多久,QQ扩列升级要多久?QQ扩列升级维护到什么时候结束
  18. android 系统的组成,简析Android 的GUI 系统组成
  19. #error和#warning使用分析
  20. mac挂载阿里云盘做本地盘【webdav-aliyundriver】【CloudMounter】

热门文章

  1. 列主元高斯消去法Matlab实现
  2. 深度学习中的一些术语和概念
  3. 调试并修理垂起固定翼(VTOL)
  4. DHCP Snooping原理和配置
  5. Unity+Vuforia开发增强现实(AR)教程——识别图的那些坑
  6. 嵌入式系统的软件框架简述
  7. vue实现时间倒计时
  8. linux pclint配置_64位系统下,执行pclint检查的问题: Unable to open include file 'stddef.h'...
  9. 滴滴顺风车整改的第 231 天,你想它吗?
  10. 【Android】逆向自动化