基于HTMLUnit的微博爬虫

本文详细介绍了使用HTMLUnit作为工具进行微博爬虫的实现过程,包括模拟浏览器行为、处理登录验证、解析HTML内容以及应对重复数据和限制。在实践中,遇到的挑战主要有微博数量限制、内容重复、需要验证码、内容提取不规则等问题,通过调整搜索时间跨度、数据库操作和验证码处理等方式部分解决了这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍
常用爬虫开源项目
新浪微博爬虫和腾讯微博爬虫

新浪爬虫的问题

总结


介绍

相关简介
即网络爬虫,是一种自动获取网页内容的程序。是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上就是针对爬虫而做出的优化。
主要分类
网络爬虫为搜索引擎从万维网下载网页。一般分为传统爬虫和聚焦爬虫。
传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。通俗的讲,也就是通过源码解析来获得想要的内容。

聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。
防爬虫:KS-WAF将爬虫行为分为搜索引擎爬虫及扫描程序爬虫,可屏蔽特定的搜索引擎爬虫节省带宽和性能,也可屏蔽扫描程序爬虫,避免网站被恶意抓取页面。



常用爬虫开源项目


Nutch logo 搜索引擎 Nutch
 Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
尽管Web搜索是漫游Internet的基本要求, 但是现有web搜索引擎的数目却在下降. 并且这很有可能进一步演变成为一个公司垄断了几乎所有的web搜索为其谋取商业利益.这显然 不利于广大Internet用户.
现在所有主要的搜索引擎都采用私有的排序算法, 而不会解释为什么一个网页会排在一个特定的位置. 除此之外, 有的搜索引擎依照网站所付的 费用, 而不是根据它们本身的价值进行排序.

Apache Nutch项目(一个网页搜索引擎)。当Nutch发展到一定程度的时候,遇到了扩展性问题,就是当存储的网页数量级别达到亿的级别之后,Nutch原始的结构很难达到高效性。正当整个team一筹莫展的时候,救世主Google出现了,Google在2003年发表了关于Google使用的分布式文件存储系统文章(The Google File System),而Nutch的开发人员意识到可以把Nutch在GFS上实现,所以经过一年的开发之后,NDFS(Nutch Distributed Filesystem)就出现了。解决了瓶颈问题之后呢,Nutch得到了极大的发展,而恰好2004年Google又放出了MapReduce的思想,那么尝到甜头的Nutch开发人员毫不犹豫的把MapReduce Model也应用到了Nutch系统里。
可是,在Nutch里面加入GFS和MapReduce之后,Nutch已经变得过于庞大,超出了一个web search engine的范围,于是2006年,NDFS和MapReduce被单独移植出来,组成了一个新的项目,就叫Hadoop。

Java多线程Web爬虫 Crawler4j

Crawler4j是一个开源的Java类库提供一个用于抓取Web页面的简单接口。可以利用它来构建一个多线程的Web爬虫。
crawler4j的使用主要分为两个步骤:
1.实现一个继承自WebCrawler的爬虫类;
2.通过CrawlController调用实现的爬虫类。
WebCrawler是一个抽象类,继承它必须实现两个方法:shouldVisit和visit。其中:
shouldVisit是判断当前的URL是否已经应该被爬取(访问);
visit则是爬取该URL所指向的页面的数据,其传入的参数即是对该web页面全部数据的封装对象Page。

Crawler.CrawController 控制爬虫,先addseed,再开启多个爬虫,并不断监听各个爬虫存活状态。
Crawler.WebCrawler 爬虫
1. Run():不断循环,每次从Frontier拿50条url,对每条url,processPage(curUrl)。
2. processPage(curURL):用PageFetcher.fetch爬取网页,如果curURL有redirect,则将redirect url的url加入Frontier,以后再调度;如果爬取正常,则先进行parse,生成Page,将新urls降入Frontier(新加入url的深度此时确定),调用visit(Page){用户自定义操作}。

Crawler.Configurations 读取crawler4j.properties中的信息
Crawler.PageFetcher 启动IdleConnectionMonitorThread,用fetch(Page, ignoreIfBinary),爬取单个Page页面。是一个static类。
Crawler.Page 一个页面
Crawler.PageFetchStatus 单个页面爬取的配置,如返回爬取状态数字所代表的含义等等。
Crawler.HTMLParser 对HTML源码进行parse,存入Page中。
Crawler.LinkExtractor 抽取出一个HTML页面中包含的所有link。
Crawler.IdleConnectionMonitorThread 用来监听连接(用来发送get请求,获取页面),其connMgr则负责HTML请求的发送

HTMLUNIT

HtmlUnitHtmlUnit is a "GUI-Less browser for Java programs". It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc... just like you do in your "normal" browser.
HtmlUnit的使用: 简介:HtmlUnit说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴,HtmlUnit提供了一系列的API,这些API可以干的功能比较多,如表单的填充,表单的提交,模仿点击链接,由于内置了Rhinojs引擎,因此可以执行Javascript

1、模拟特定浏览器,也可以指定浏览器的相应版本(HtmlUnit最新版2.13现在可以模拟的浏览器有Chrome/FireFox/IE)
 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_24);
2、查找特定元素,通过get或者XPath可以从HtmlPage中获得特定的Html元素.例如;
DomElement plc_main=page.getElementById("plc_main");
DomElement code_box=(DomElement) pl_common_sassfilter.getByXPath("//div[@class='code_box clearfix']").get(0);

3,模拟表单的提交 如登陆所用的代码所示;
HtmlForm loginform = logonPage.getFormByName("loginform");
HtmlTextInput uid = loginform.getInputByName("u");
uid.click();//点击获得焦点
uid.type(Config.getAccount());
HtmlPasswordInput pwd = loginform.getInputByName("p");
pwd.click();
pwd.type(Config.getPassword());

4,获取信息如微博内容等如新浪微博。
DomNodeList<HtmlElement> dls = pl_weibo_direct.getElementsByTagName("dl");
DomElement dl= dls.get(0);        
int index = 0;
while(dl != null ){
DomElement em=feed_list_content.getElementsByTagName("em").get(0);
String content = em.getTextContent();
newlist.add(content);
index++;
dl = dls.get(index);}

2.模拟登陆,找到微博的content所在位置。
3.得到微博数据,保存在数据库中,数据库用的是MYSQL
逻辑其实很简单就是要熟悉一下HTMLunit所提供的一些类,然后XPath语法,再熟悉一些基础的数据库知识就能完成爬微博了。

腾讯微博也是同样的思路。一些区别就是
1.页面解析不同。
2.URL的一些特点不同。

新浪爬虫的问题总结

新浪微博爬虫的一些问题:
首先就是微博数量的限制,从搜索页面 关键字开始搜索 只能搜索50页的微博数据。然后每一页20条,只能搜索1000条,这与实时微博数量肯定不相匹配。
所以可以用高级搜索从2009年开始搜索这个需要不停的试验看时间到哪里能组成50页微博。因为新浪微博无论然后我搜索都是只能显示50页的数据。
如本田雅阁 为例,可以分成五次搜索,第一次是2009年到2010年,在这个时间段只有33页的数据,然后从2010年1.1到2011.1.1有50页数据,然后往下推,有的时间段只要设置五六个月就有50页数据,总之这个没什么规律,大概就是时间越往后,微博的数量越多吧。所以这个编程的时候到50页之后 url的连接下一页就没有了。这是一个局限。

第二个问题就是微博内容重复问题,如该连接
http://s.weibo.com/wb/%25E6%259C%25AC%25E7%2594%25B0%25E9%259B%2585%25E9%2598%2581&xsort=time&scope=ori&timescope=custom:2013-01-01-0:2014-04-23-0&page=8
本田雅阁为例,在该页基本所有的微博都是同种内容。根据我的观察,这种品牌性质的微博,更多的是营销广告微博。当然可以用微博验证这种办法来进行刷选。但是真正有意义的,原创的微博,数量少的可怜。只有几百条的规模。
对于删除相同微博还有一些办法,最近比较有效的是在数据库下面操作,用select distinct content from weibo where program='本田雅阁' into outfile 'D:/本田雅阁.txt'; 还是能删除大部分重复微博。
或者对于大部分相同只有网址不同的情况。可以用delete from weibo where content LIKE '%铃木“大型车”将国产 与本田雅阁同级%';或者别的一些特征特别明显的词或者短语。

第三个问题就是,新浪虽然只提供这么点数据,还要处处限制。当程序运行到20个页面时,就会出现需要人工输入验证码的问题,防止爬虫影响它服务器。这个解决是模仿登陆验证码的方法解决的。就是把这个需要输入的验证码,给弄出来imageReader到一个JFrame中再人工输入,click进去,基本还是能解决该问题。


第四个问题,就是微博内容 content 在页面中不规律体现的,如所有的微博内容都是在一个<em></em>中只要em.getTextContent().即可。因为不规律有的em下是赞,是空格等。解决办法就是用一个判断,发现em只要不是真正的内容就不会带有任何属性。反之就会有class 属性。用一个判断hasAttribute()可以将赞和空格给踢出去。

第五个问题,就是id 定位不同的问题,用一般搜索时定位ID为pl_weibo_direct,用高级搜索时微博内容定位ID为pl_wb_feedlist,<div id="pl_wb_feedlist" smartconf="type=1">,当然都是一些细节。
总结:
虽然问题还是很多,爬数据的效果不太好。但是,可以肯定新浪微博,大部分数据还是能通过URL找到,新浪公司大规模的进行删除是不可能的。假设如果我这个用户在很久以前2009年发了一条微博支持本田雅阁的,我可以通过我的微博这个链接,看到该微博与本田雅阁相关的内容。所以与关键字相关的微博还是存在页面中的,只是新浪微博自己提供的搜索功能,不强大比较局限吧。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值