一、写在前面

(本专栏分为“java版微博爬虫”和“python版网络爬虫”两个项目,系列里所有文章将基于这两个项目讲解,项目完整源码已经整理到我的Github,有兴趣的可以去看下,链接地址在文末。)

网络爬虫根据需求的不同也分不同种类:

1.一种是爬取网页链接,通过url链接得到这个html页面中指定的链接,把这些链接存储起来,再依次以这些链接为源,再次爬取连接指向html页面中的链接……如此层层递归下去,常用的方法是广度优先或者深度优先,根据爬取层次需求不同而选择不同的方法达到最优效果,爬虫的效率优化是一个关键。

搜索引擎的第一个步骤就是通过爬虫得到需要索引的链接或数据,存放于数据库,然后对这些数据建立索引,然后定义查询语句,解析查询语句并利用检索器对数据库里的数据进行检索。

2.一种是爬取数据信息,如文本信息、图片信息等,有时需要做数据分析,通过某种手段来获取数据样本以供后续分析,常用的方法是爬虫获取指定数据样本或利用现有的公共数据库。本文的微博爬虫属于第二种类,根据自定义搜索关键字爬取微博信息数据。

对于网络爬虫原理,其实并不复杂。基本思路是:由关键字指定的url把所有相关的html页面全抓下来(html即为字符串),然后解析html文本(通常是正则表达式或者现成工具包如jsoup),提取微博文本信息,然后把文本信息存储起来。

重点在于对html页面源码结构的分析,不同的html需要不同的解析方法;还有就是长时间爬取可能对IP有影响,有时需要获取代理IP,甚至需要伪装浏览器爬取。

对于微博,通常情况下是必须登录才能看到微博信息数据(比如腾讯微博),但是有的微博有搜索机制,在非登录的情况下可以直接通过搜索话题来查找相关信息(如新浪微博、网易微博)。考虑到某些反爬虫机制,如果一个账号总是爬取信息可能会有些影响(比如被封号),所以本文采用的爬虫都是非登录、直接进入微博搜索页面爬取。这里关键是初始url地址。

二、网页分析

举个例子,对于有搜索机制的微博,如新浪微博和网易微博:(这里尤其要注意地址及参数!)

新浪微博搜索话题地址:http://s.weibo.com/weibo/苹果手机&nodup=1&page=50

网易微博搜索话题地址:http://t.163.com/tag/苹果手机

分别来看下网页截图和对应网页源码:

(1) 新浪微博:

(2) 网易微博:

我们需要做的就是把微博的文本提取出来,这里有些特征信息:根据关键字搜到的微博,其关键字会被标红,在html源码里有体现,分别查看两个网页的源代码。

可以看到,新浪微博的源码全部为html标签,为了反爬虫故意将源码混乱,并且汉字也做了处理,显示汉字的utf-8编码而不是直接显示汉字,不太好找,这里就需要查找红色字体color:red的部分,其中\u82f9\u679c\u624b\u673a<\span>中间夹着的哪些utf8编码其实就是关键字“苹果手机”。后面的那些utf8编码就是本条微博的文本内容。

而网易微博在这方面就要看起来容易许多,至少html里直接显示的是汉字,比较好找,而且微博文本部分其实是以json格式体现的,直接解析json就可以提取文本数据了,当然也可以直接用正则。

三、爬取微博

这里先写个简单的爬虫,原理都差不多,就拿网易微博为例,先说下爬虫程序需要用到的工具包:

httpclient-4.3.1.jar  -------建立HTTP链接,用于从url获取html

httpcore-4.3.jar

httpmime-4.3.1.jar

httpclient-cache-4.3.1.jar

fluent-hc-4.3.1.jar

fastjson-1.1.41.jar   ------解析json的工具包

jsoup-1.7.3.jar      -------解析xml,html的工具包

dom4j-1.6.1.jar     -------读写xml的工具包

commons-lang-2.1.jar

commons-logging-1.2.jar

commons-codec-1.8.jar

总体思路:

  1. getHTML()方法:从url得到html字符串。

这里有两个关键点:

(1) 设置用户cookie策略,屏蔽掉cookie rejected的报错,当然可以不设置,直接用默认的client,即是CloseableHttpClient client = HttpClients.createDefault();创建的客户端,但是会报错;设置cookie的代码如下:

CookieSpecProvider cookieSpecProvider = new CookieSpecProvider(){public CookieSpec create(HttpContext context){return new BrowserCompatSpec(){@Overridepublic void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException {//Oh, I am easy;}};}};Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider> create().register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()).register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()).register("easy", cookieSpecProvider).build();

(2) 设置socket超时socketTimeout和连接超时connectTimeout,这很关键,如果不设置的话,当网络不好的情况下,某次请求没有及时得到响应,程序可能会卡死。但是设置连接超时,超时之后再自动重连就可以避免这个问题。代码如下:

RequestConfig requestConfig = RequestConfig.custom().setCookieSpec("easy").setSocketTimeout(5000) //设置socket超时时间.setConnectTimeout(5000)  //设置connect超时时间.build();

2.isExitHTML()方法:

判断html是否合法(有效html,有微博内容的),有时候会出现页面不存在的情况,是因为该关键字没有微博信息,这是页面有提示:“没有找到相关的微博呢,换个关键词试试吧!”如下图;

3.writeWeibo2txt()方法:

正则解析(这里主要解析微博文本内容content、用户id、发文时间prettyTime),得到微博文本数据:控制台输出、写到txt文件;

(这里没有用jsoup去解析html,直接用的正则,有时间后面再写jsoup解析html的,比正则方便,当然对正则表达式这个工具掌握很熟练的朋友可以忽略……)

我的博客里另外有一篇正则教程完全总结,可以去看下:正则表达式总结

本来网易微博的源代码里嵌入了json元素,前面的html标签的都不是微博文本数据,在这个标签后面        <scriptid="data_searchTweet" type="application/json">才是json格式包括的微博文本,本来打算先把json串用正则匹配出来,后来发现,直接匹配关键字岂不更好?但这里要注意的是匹配的时候可能会有很多换行符之类的东西,我这里只匹配了三个field,正则表达式"id":\s"\d{19}",(\n?)|(\s?)"content":\s".?",(\n?)|(\s?)"prettyTime":\s".?"

顺便推荐一个检测正则的工具:http://tool.oschina.net/regex?optionGlobl=global

把源码贴上来吧:

/*** @note 1.根据搜索关键词从指定url得到相应的html页面,并验证其合法性;*       2.得到微博样本:写到txt文件里* * @author DianaCody* @since 2014-09-26 15:08**/import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BestMatchSpecFactory;
import org.apache.http.impl.cookie.BrowserCompatSpec;
import org.apache.http.impl.cookie.BrowserCompatSpecFactory;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;public class Weibo163 {private String getHTML(String url) throws URISyntaxException, ClientProtocolException, IOException {//采用用户自定义cookie策略,不显示cookie rejected的报错CookieSpecProvider cookieSpecProvider = new CookieSpecProvider(){public CookieSpec create(HttpContext context){return new BrowserCompatSpec(){@Overridepublic void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException {}};}};Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider> create().register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()).register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()).register("cookie", cookieSpecProvider).build();RequestConfig requestConfig = RequestConfig.custom().setCookieSpec("cookie").setSocketTimeout(5000) //设置socket超时时间.setConnectTimeout(5000)  //设置connect超时时间.build();CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieSpecRegistry(r).setDefaultRequestConfig(requestConfig).build();HttpGet httpGet = new HttpGet(url);httpGet.setConfig(requestConfig);String html = "html获取失败"; //用于验证是否取到正常的htmltry{CloseableHttpResponse response = httpClient.execute(httpGet);html = EntityUtils.toString(response.getEntity());//System.out.println(html); //打印返回的html         } catch (IOException e) {e.printStackTrace();}return html;}private boolean isExistHTML(String html) throws InterruptedException {boolean isExist = false;Pattern pNoResult = Pattern.compile("\\\\u6ca1\\\\u6709\\\\u627e\\\\u5230\\\\u76f8"+ "\\\\u5173\\\\u7684\\\\u5fae\\\\u535a\\\\u5462\\\\uff0c\\\\u6362\\\\u4e2a"+ "\\\\u5173\\\\u952e\\\\u8bcd\\\\u8bd5\\\\u5427\\\\uff01"); //没有找到相关的微博呢,换个关键词试试吧!(html页面上的信息)Matcher mNoResult = pNoResult.matcher(html);if(!mNoResult.find()) {isExist = true;}return isExist;}private void writeWeibo2txt(String html, String savePath) throws IOException {File htmltxt = new File(savePath); //新建一个txt文件用于存放爬取的结果信息FileWriter fw = new FileWriter(htmltxt);BufferedWriter bw = new BufferedWriter(fw);//regex-----"id":\s"\d{19}",(\n*?)|(\s*?)"content":\s".*?",(\n*?)|(\s*?)"prettyTime":\s".*?"Pattern p = Pattern.compile("\"id\":\\s\"\\d{19}\",(\\n*?)|(\\s*?)\"content\":\\s\".*?\",(\\n*?)|(\\s*?)\"prettyTime\":\\s\".*?\"");Matcher m = p.matcher(html);while(m.find()) {System.out.println(m.group());bw.write(m.group());}bw.close();}public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {Weibo163 crawler = new Weibo163();String searchword = "iPad"; //搜索关键字为"iPad"的微博html页面String html = crawler.getHTML("http://t.163.com/tag/"+searchword);String savePath = "e:/weibo/html.txt"; //输出到txt文件的存放路径if(html != "html获取失败") {if(crawler.isExistHTML(html)) {System.out.println(html);crawler.writeWeibo2txt(html, savePath);}}//Pattern p = Pattern.compile("<script id=\"data_searchTweet\" type=\"application/json\">.+?<\script>"); //<script id="data_searchTweet" type="application/json">.*?<\script>//Matcher m = p.matcher(html);//html = crawler.getHTML("http://s.weibo.com/weibo/"+searchword+"&nodup=1&page="+1);//System.out.println(html);}}

程序运行截图:

该java爬虫项目源码github地址:https://github.com/DianaCody/Spider_SinaTweetCrawler_java。

网络爬虫---牛刀小试相关推荐

  1. python网络爬虫初识_python爬虫(一)初识爬虫

    什么是爬虫? 中文名(网络爬虫) 外文名(web crawler) 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程 ...

  2. 【网络爬虫】(1) 网络请求,urllib库介绍

    各位同学好,今天开始和各位分享一下python网络爬虫技巧,从基本的函数开始,到项目实战.那我们开始吧. 1. 基本概念 这里简单介绍一下后续学习中需要掌握的概念. (1)http 和 https 协 ...

  3. Python网络爬虫--urllib

    本篇随便记录学习崔庆才老师编著的<Python3 网络爬虫开发实战>以及urllib标准库使用 urllib库是Python内置的HTTP请求库,包含四个模块: request:最基本的H ...

  4. python网络爬虫程序技术,Python网络爬虫程序技术

    spContent=该课程是2018年广东省精品在线开放课程.课程主要以爬取学生信息.爬取城市天气预报.爬取网站图像.爬起图书网站图书.爬取商城网站商品等5个项目为依托,讲解Web.正则表达式.Bea ...

  5. python之网络爬虫

    一.演绎自已的北爱 踏上北漂的航班,开始演奏了我自已的北京爱情故事 二.爬虫1 1.网络爬虫的思路 首先:指定一个url,然后打开这个url地址,读其中的内容. 其次:从读取的内容中过滤关键字:这一步 ...

  6. 精通Python网络爬虫:核心技术、框架与项目实战.1.1 初识网络爬虫

    摘要 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理.在大数据时代,信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高.此时,我们 ...

  7. 20161124网络爬虫技术学习

    参考书籍:<自己动手写网络爬虫> 网络爬虫的基本操作是抓取网页. "打开"网页的过程其实就是浏览器作为一个浏览的"客户端",向服务器端发送了一次请穷 ...

  8. 目前网络上开源的网络爬虫以及一些简介和比较

    2019独角兽企业重金招聘Python工程师标准>>> 目前网络上开源的网络爬虫以及一些简介和比较 目前网络上有不少开源的网络爬虫可供我们使用,爬虫里面做的最好的肯定是google ...

  9. 爬虫书籍-Python网络爬虫权威指南OCR库 NLTK 数据清洗 BeautifulSoup Lambda表达式 Scrapy 马尔可夫模型

    Python网络爬虫权威指南 编辑推荐 适读人群 :需要抓取Web 数据的相关软件开发人员和研究人员 作为一种采集和理解网络上海量信息的方式,网页抓取技术变得越来越重要.而编写简单的自动化程序(网络爬 ...

最新文章

  1. CUDA make_float3和make_float4
  2. nssl1337-矩形统计【单调栈】
  3. CSS之Multi-columns的列数和列宽
  4. Oracle SQL语句执行步骤
  5. 和平精英体验服服务器更新维护什么意思,和平精英8月9日体验服官方申请地址 和平精英更新6项内容需要多注意!和平精英8月9日更新时间确定...
  6. rocketmq在Kubernetes(k8s)中的集群配置,2m-2s-async:多Master多Slave模式,异步复制
  7. 麦子学院bootstrap实战项目官网,后台,jquery.singlePageNav.min.js ,wow.min.js,animate.css使用...
  8. 网页制作篇(智慧树网站马红老师)-基础知识总结2(标记的属性篇)
  9. css 实现一个尖角_css中尖角的制作实例方法总结
  10. c语言else的用法,else的用法
  11. 百度网盘里的加密视频为什么不能直接用点盾云播放?
  12. Windows 10开启Teredo隧道连接IPV6
  13. raspberry 防火墙_用Raspberry Pi对您的家庭网络进行防火墙
  14. SyntaxError: Non-UTF-8 code starting with '\xb5' in file“问题解决办法
  15. 如何转换为YOLO txt格式
  16. H.264 H.265 数据量及存储量计算
  17. 眼光毒辣!这家投资团队让 “鸡蛋森” 马克安德森投了都说好
  18. temp = (temp 0x55555555) + ((temp 0xaaaaaaaa) 1)
  19. linux kernel 网络协议栈之GRO(Generic receive offload)
  20. CSS实现圆角,三角,五角星,五边形,爱心,12角星,8角星,圆,椭圆,圆圈,八卦等等

热门文章

  1. JAVA8 Metaspace内容_JDK8 metaspace调优
  2. 使用C++模拟实现道具店购物功能
  3. linux 命令行随机数,Linux系统产生随机数的6种方法
  4. 矩阵的行列式(递归C++)
  5. AAAI 2023 | 双域风格图像和谐化
  6. 寻仙手游微信39服务器,寻仙手游ios手Q14区与ios手Q16区数据互通公告
  7. 好男人的15条标准[转帖]
  8. 《热血传奇h5》win系统一键服务器,传奇H5养鯤传奇2020总结版武圣之战Win一键即玩服务端...
  9. js-event(事件对象)详解
  10. 数字图像处理 matlab实现