这篇文章抓取使用的是jsoup,要求简单的情况下比起httpclient确实方便的多。有启示性但对我的需求来说不太适用,比如没有登陆。

项目需要在抓取新浪微博搜索结果数据,顺手做了个工具,以实现在新浪微博搜索中自动抓取配置的关键字的搜索结果。在此分享一下。

先看一下新浪微博搜索结果页面的源码:

可以看到,得到的并不是普通html,都是通过js调用的。其中汉字全部是经过编码的。文本元素全部都是上图红框中的格式,要得到搜索结果就需要对红框中的文本进行解析。其中用到了jsoup 和 fastjson jar包,需要自行下载。

jsoup: http://jsoup.org/download

fastjson:http://sourceforge.net/projects/fastjson

搜索结果抓取核心类:

  1. import java.io.IOException;
  2. import java.text.ParseException;
  3. import java.util.ArrayList;
  4. import java.util.Date;
  5. import java.util.List;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. import org.apache.solr.common.SolrInputDocument;
  9. import org.jsoup.Jsoup;
  10. import org.jsoup.nodes.Document;
  11. import org.jsoup.nodes.Element;
  12. import org.jsoup.safety.Whitelist;
  13. import org.jsoup.select.Elements;
  14. import com.alibaba.fastjson.JSON;
  15. public class WeiboFetcher extends AbstractFetcher {
  16. // 文本块正文匹配正则
  17. private final String blockRegex = "<script>STK\\s&&\\sSTK\\.pageletM\\s&&\\sSTK\\.pageletM\\.view\\(.*\\)";
  18. private Pattern pattern = Pattern.compile(blockRegex);
  19. private static Whitelist whitelist = new Whitelist();
  20. static{
  21. // 只保留em标签的文本
  22. whitelist.addTags("em");
  23. }
  24. @Override()
  25. public List<SolrInputDocument> fetch() {
  26. List<SolrInputDocument> newsResults = new ArrayList<SolrInputDocument>();
  27. newsResults = WeiboResult();
  28. System.out.println("WeiboFetcher Over: " + newsResults.size());
  29. return newsResults;
  30. }
  31. /**
  32. * 获取关键字搜索结果
  33. * @return
  34. */
  35. private List<SolrInputDocument> WeiboResult() {
  36. String keyWord = null;
  37. List<SolrInputDocument> newsResultList = new ArrayList<SolrInputDocument>();
  38. // 获取配置的关键字
  39. List<String> keyWordList = KeywordReader.getInstance().getKeywords();
  40. for (String keyWordLine : keyWordList) {
  41. // 转换为新浪微博搜索接受的格式
  42. keyWord = policy.getKeyWord(keyWordLine,null);
  43. newsResultList.addAll(getWeiboContent(keyWord));
  44. }
  45. return newsResultList;
  46. }
  47. /**
  48. * 获取搜索结果
  49. * @param keyWord
  50. * @return
  51. */
  52. private List<SolrInputDocument> getWeiboContent(String keyWord){
  53. System.out.println("fetch keyword: " + keyWord);
  54. List<SolrInputDocument> resultList = new ArrayList<SolrInputDocument>();
  55. for(int i = 0; i < depth; i++){
  56. String page = "";
  57. if(i > 0){
  58. page = "&page=" + (i+1);
  59. }
  60. //抓取返回50个内容
  61. try {
  62. System.out.println("fetch url page depth " + (i + 1));
  63. // 注意&nodup=1
  64. Document doc = Jsoup.connect(
  65. "http://s.weibo.com/weibo/" + keyWord+"&nodup=1" + page).get();
  66. String source = doc.html();
  67. // 匹配文本块
  68. Matcher m = pattern.matcher(source);
  69. while(m.find()){
  70. String jsonStr = m.group();
  71. jsonStr = jsonStr.substring(jsonStr.indexOf("{"), jsonStr.lastIndexOf(")"));
  72. // 解析json,转换为实体类
  73. WeiboBlock block = JSON.parseObject(jsonStr, WeiboBlock.class);
  74. if(block.getHtml().trim().startsWith("<div class=\"search_feed\">")){
  75. doc = Jsoup.parse(block.getHtml());
  76. }
  77. }
  78. List<Element> elements = getAllElement(doc);
  79. if(elements == null || elements.size() == 0){
  80. System.out.println("No more urls to fetch with current keyword." );
  81. return resultList;
  82. }
  83. for (Element elem : elements) {
  84. String url = elem.select(".date").last().attr("href");
  85. String dateS = elem.select(".date").last().attr("date");
  86. String content = null;
  87. Date date = null;
  88. String content_text = null;
  89. String title = null;
  90. if (!isCrawledUrl(url)){
  91. if (url != null) {
  92. if (dateS != null && !"".equals(dateS)) {
  93. try {
  94. date = sdf.parse(changeString2Date(dateS));
  95. } catch (ParseException e) {
  96. e.printStackTrace();
  97. }
  98. }
  99. if (date != null) {
  100. elem.getElementsByClass("info W_linkb W_textb").remove();
  101. content = Jsoup.clean(Jsoup.clean(elem.select(".content").html(), whitelist), Whitelist.none());
  102. title = this.parseTitle(content);
  103. url = elem.select(".date").last().attr("href");
  104. SolrInputDocument sid = buildSolrInputDocumentList(url, content, title, date);
  105. if (sid != null && sid.size() > 0) {
  106. resultList.add(sid);
  107. }
  108. }
  109. }else {
  110. System.out.println("current Url: ---------null------------" );
  111. }
  112. }
  113. }
  114. } catch (IOException e) {
  115. e.printStackTrace();
  116. }
  117. }
  118. return resultList;
  119. }
  120. /**
  121. * 获取所有的结果正文节点
  122. * @param doc
  123. * @return
  124. */
  125. private List<Element> getAllElement(Document doc) {
  126. List<Element> resultList = new ArrayList<Element>();
  127. Elements elems = doc.select(".search_feed .feed_list");
  128. for (Element element : elems) {
  129. resultList.add(element);
  130. }
  131. return resultList;
  132. }
  133. @Override
  134. protected boolean isCrawledUrl(String url) {
  135. return isAvaliableUrl(url);
  136. }
  137. /**
  138. * 生成标题
  139. * @param htmlContent
  140. * @return
  141. */
  142. private String parseTitle(String htmlContent) {
  143. if (htmlContent == null || htmlContent.trim().equals(""))
  144. return null;
  145. String title = htmlContent;
  146. title = title.trim();
  147. for (int i = 0; i < title.length(); i++) {
  148. if (String.valueOf((title.charAt(i))).matches("[,.\\?\\!\\.,]")) {
  149. title = title.substring(0, i);
  150. break;
  151. }
  152. }
  153. return title;
  154. }
  155. }

结果实体类:

  1. public class WeiboBlock{
  2. private String pid;
  3. private String js;
  4. private String css;
  5. private String html;
  6. public WeiboBlock(){}
  7. public String getPid() {
  8. return pid;
  9. }
  10. public void setPid(String pid) {
  11. this.pid = pid;
  12. }
  13. public String getJs() {
  14. return js;
  15. }
  16. public void setJs(String js) {
  17. this.js = js;
  18. }
  19. public String getCss() {
  20. return css;
  21. }
  22. public void setCss(String css) {
  23. this.css = css;
  24. }
  25. public String getHtml() {
  26. return html;
  27. }
  28. public void setHtml(String html) {
  29. this.html = html;
  30. }
  31. }

关键字生成策略类:

  1. public class SinaKeyWordsPolicy implements KeyWordsPolicy {
  2. @Override
  3. public String getKeyWord(String keyWordLine, String siteLine) {
  4. String keyWord = null;
  5. keyWordLine = keyWordLine.replaceAll("\"", "");
  6. keyWordLine = keyWordLine.replaceAll("AND", " ");
  7. keyWordLine = keyWordLine.replaceAll("OR", "|");
  8. if (keyWordLine.contains("|")) {
  9. String[] tempStrings = keyWordLine.split("|");
  10. if (tempStrings.length > 3) {
  11. for (int i=0; i<3 ;i++) {
  12. keyWord += tempStrings[i];
  13. keyWord += "|";
  14. }
  15. }else {
  16. keyWord = keyWordLine;
  17. }
  18. }else {
  19. keyWord = keyWordLine;
  20. }
  21. return java.net.URLEncoder.encode(java.net.URLEncoder.encode(keyWord));
  22. }
  23. }

关键字配置文件使用文本文件即可,每行一组关键字,格式类似如下:

"key1"

"key1"AND"key2"

"key1"AND("key2"OR"key3")

附:项目源码已经整理并上传GitHub, 访问地址:https://github.com/Siriuser/WeiboCrawler

需要源码的话请自行下载。

本文出自 “果壳中的宇宙” 博客,请务必保留此出处http://williamx.blog.51cto.com/3629295/1047832

新浪微博搜索结果数据抓取相关推荐

  1. php天猫列表数据抓取,如何翻页抓取网页数据——以采集天猫搜索列表为例

    我们在抓取数据时,通常不会只抓取网页当前页面的数据,往往都会继续抓取翻页后的数据.本文就为大家介绍,集搜客GooSeeker网络爬虫如何在进行数据抓取时,自动抓取翻页后的数据. 在MS谋数台的爬虫路线 ...

  2. 关于Python爬虫原理和数据抓取1.1

    为什么要做爬虫? 首先请问:都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据 ...

  3. Python学习笔记——爬虫原理与Requests数据抓取

    目录 为什么要做网络爬虫? 通用爬虫和聚焦爬虫 HTTP和HTTPS 客户端HTTP请求 请求方法 HTTP请求主要分为Get和Post两种方法 常用的请求报头 1. Host (主机和端口号) 2. ...

  4. python爬虫百度百科-python爬虫(一)_爬虫原理和数据抓取

    本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...

  5. python教程怎么抓起数据_介绍python 数据抓取三种方法

    三种数据抓取的方法正则表达式(re库) BeautifulSoup(bs4) lxml *利用之前构建的下载网页函数,获取目标网页的html,我们以https://guojiadiqu.bmcx.co ...

  6. Uipath 学习栏目基础教学:10、数据抓取

    提示:专栏解锁后,可以查看该专栏所有文章. 文章目录 一.数据抓取 1.1表格数据抓取 1.2 搜索结果爬取 提示:以下是本篇文章正文内容,下面案例可供参考 一.数据抓取 UiPath Studio ...

  7. b站视频详情数据抓取,自动打包并发送到指定邮箱(单个或者群发)

    BiLiBiLi Time: 2020年11月6日19:44:58 Author: Yblackd BiLiBiLi BiLiBiLi 介绍 软件架构 安装教程 使用说明 源码下载 BiLiBiLi ...

  8. Ajax异步数据抓取

    1.简介 1 有时候我们在用requests抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览 2 器中可以看到正常显示的页面数据,但是使用requests得到的结果并没有.这是因为req ...

  9. 李沐【实用机器学习】1.3网页数据抓取

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.数据抓取工具 二.实例解析 总结 前言 网页数据抓取目标:在一个网站里面感兴趣的数据抓取出来 数据特点:噪点较多, ...

最新文章

  1. Android 设置透明的方法
  2. C语言实现简易通讯录
  3. 【渝粤教育】国家开放大学2018年秋季 1021t劳动与社会保障法 参考试题
  4. (转)nmake学习笔记
  5. 无心剑随感《最完美的图形——圆》
  6. php发送http put/patch/delete请求
  7. GDAL插值使用示例
  8. 没有的功能,直接回答并不好
  9. unity数组或链表需要空间很大赋值与调用
  10. vm虚拟机获取ip地址
  11. 东大oj1155 等凹函数
  12. Qt Design Studio安装教程
  13. 联通4G业务或沿用沃品牌 不推无限量套餐
  14. 操作系统第五章 设备管理(上)笔记
  15. python 表格查询,Python实现数据表查找
  16. Oracle中Blob和Clob类型的区别
  17. 122.买卖股票的最佳时机 II
  18. js根据日期时间区间获取季度Q1-Q4列表
  19. pycharm切换文件夹_Pycharm中一些不为人知的技巧
  20. 全国计算机应用基础统考成绩查询,网络教育统考成绩查询的方法有哪些

热门文章

  1. python爬虫——获取新闻标题
  2. 曾为你泪水狂流 曾为你万事都低头
  3. struts2.1.8 StrutsPrepareAndExecuteFilter 关于静态资源处理问题
  4. 从BAE到SAE,从SAE又回到BAE
  5. Schnorr数字签名方案
  6. 逸仙电商逆流而上 国货化妆品的“进化与蝶变”
  7. DOM编程 事件正则表达式表单校验
  8. (已解决)多卡训练时报错RuntimeError: grad can be implicitly created only for scalar outputs
  9. FPGA小白学习之路(5)clk为什么要用posedge,而不用negedge(转)
  10. Resultset获取数据