转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自【大学之旅_谙忆的博客】

简单的通过关键字,爬出百度知道的一些搜索数据。
例如:问题,提问时间;答案文本,答案时间,点赞数,拍砖数,回答人,回答人级别,搜索的关键字等。

答案可以有多个,每个问题有多个答案应都保存。保存数据在MySql中。

在这里需要用到一个牛人的爬虫框架:
WebMagic
网址:http://webmagic.io/docs/zh/

我用的是IEDA工具,建立的是Maven项目。

要搞爬虫,一些基础的学习是不可少的,比如HTML,JSP等前台知识,知道怎么解析xml文档(利用XPath),用开发工具(推荐Intellij IDEA),MySQL,Maven也可以学习等等。

下面就开始讲怎么抓取百度知道的数据了。

我们用百度知道搜索的时候,可以看地址栏:
https://zhidao.baidu.com/search?ct=17&pn=0&tn=ikaslist&rn=10&word=%E7%A4%BE%E4%BF%9D%E8%BD%AC%E7%A7%BB&fr=wwwt

这里关键词的变量名是word。那么其他变量与值可以不用管它。

缩减一下地址:
https://zhidao.baidu.com/search?word=社保迁移

还有重要的一点是,百度知道的html的编码是GBK的!注意编码不要搞错了。

这个时候我们就可以利用这个地址来进行一些事情了。

需要学会用浏览器查看网页源码哦。

通过这种方式,我们可以找出标题的规律,进而通过XPath解析,得到标题名!

这些数据(标题,问题描述,答案,时间等)都是可以通过上面方式得到的!

这里有个小问题,就是点赞数和拍砖数这样是找不到正确的方式的,因为那里是动态生成。

在这里做一个演示:

通过火狐浏览器的查看元素源码,是这样的。

通过在地址栏前面加: view-source: 可以看网页源码。
一般点击鼠标右键,可以直接看网页源码。

这个时候,我们并不可以在源码中看到刚刚的代码。

也就是说,我们抓取网页的源码的时候,获取到的html也是没有那个的,怎么办,这个时候,我们会发现,

<span alog-action="qb-zan-btnbestbox" class="iknow-qb_home_icons evaluate evaluate-32" id="evaluate-2225390772" data-evaluate="7" >
</span>

data-evaluate=”7”
正好与点赞数7一样!
继续对比一下其他页面,会发现这个属性的值就是点赞数!

那么好办了,通过XPath然后加工一下,一样可以获取此值。
拍砖数一样的分析,然后获取就行!

至于其他的数据,差不多都是这样分析的。

开始本来想做成Web应用,结果WebMagic爬虫框架只能在main线程才能运行,所以就只做了一个简单的用main函数启动的应用了。

用到了MyBatis和Spring。主要是为了操作数据库简单一点。
你可以不用框架的,主要代码只有这个类的代码:

package cn.hncu;import cn.hncu.model.Answer;
import cn.hncu.model.Keyword;
import cn.hncu.model.KeywordProblemKey;
import cn.hncu.model.Problem;
import cn.hncu.service.KeywordService;
import cn.hncu.service.KeywordServiceImpl;
import cn.hncu.tool.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;import javax.xml.xpath.XPath;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.*;/*** Created with IntelliJ IDEA.* User: 陈浩翔.* Date: 2017/2/27.* Time: 下午 6:29.* Explain:*/
public class Entrance implements PageProcessor {private Logger logger = LoggerFactory.getLogger(Entrance.class);private static ApplicationContext context;private static KeywordService keywordService;//搜索的关键字private static String keyword = "社保转移";//百度知道的搜索前缀private static String url = "https://zhidao.baidu.com/search?word=";//设置抓取页数private static Integer pages = 20;private Site site = Site.me().setCharset("gbk").setRetrySleepTime(4).setSleepTime(100);private static String keywordId ;private List<Map<String,String>> lists;@Overridepublic void process(Page page) {Html html = page.getHtml();//问题String problem = html.xpath("//span[@class='ask-title']/text()").toString();logger.info("问题:"+problem);//提问者String problemAnthor = html.xpath("//a[@alog-action='qb-ask-uname']/text()").toString();//logger.info("提问者:"+problemAnthor);//问题描述String problemDescribe = html.xpath("//span[@class='con']/text()").toString();//logger.info("问题描述:"+problemDescribe);//提问时间if(problem==null) {lists = new ArrayList<Map<String, String>>();List<String> strs = html.xpath("//dd/span[@class='mr-8']/text()").all();List<String> quizTimes = new ArrayList<String>();for (int i=0;i<strs.size();i++) {//logger.info(strs.get(i)+"  "+strs.get(i).matches("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]"));if(strs.get(i).matches("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]")){quizTimes.add(strs.get(i));}}List<String> portionProblems = html.xpath("//a[@class='ti']/text()").all();//logger.info("quizTimes.size():" + quizTimes.size());//logger.info("portionProblems.size():" + portionProblems.size());if(quizTimes.size()==portionProblems.size()) {for (int i=0;i<quizTimes.size();i++) {Map<String,String> map = new HashMap<String,String>();map.put("quizTimes",quizTimes.get(i));map.put("portionProblems",portionProblems.get(i));lists.add(map);//logger.info("部分问题:" + lists.get(i).get("portionProblems"));//logger.info("时间:" + lists.get(i).get("quizTimes"));}}}//最佳回答String bestAnswer =html.xpath("//pre[@class='best-text mb-10']").toString();//图片文字无法处理if(bestAnswer==null){bestAnswer =html.xpath("//div[@class='best-text mb-10']").toString();}//logger.info("最佳回答:"+bestAnswer);//回答者String answerAuthor = html.xpath("//a[@class='mavin-name f-14 mr-10']/text()").toString();//如果回答者为NULL-有可能是其他的没有认证的人回答的if(answerAuthor==null){answerAuthor = html.xpath("//div[@class='grid f-aid ff-arial']/p/a[@class='user-name']/text()").toString();}//如果回答者还是为NULL-有可能是网上的人贡献的if(answerAuthor==null){answerAuthor = html.xpath("//div[@class='grid f-aid ff-arial']/p[@class='mb-5']/span/text()").toString();}//logger.info("回答者:"+answerAuthor);//回答者等级String anthorGrade = html.xpath("//a[@class='mavin-reply-icon f-orange']/text()").toString();//如果回答者等级为NULL-有可能是其他的没有认证的人回答的if(anthorGrade==null){anthorGrade = html.xpath("//div[@class='grid f-aid ff-arial']/p[@class='mb-5']/a[@class='i-gradeIndex']").toString();if(anthorGrade!=null){anthorGrade = "LV"+anthorGrade.substring(anthorGrade.lastIndexOf("Index-")+6,anthorGrade.lastIndexOf(" mr-10"));}}if(answerAuthor!=null&&anthorGrade==null){anthorGrade ="0";}//logger.info("回答者等级:"+anthorGrade);//推荐时间String answerTime = html.xpath("//span[@class='grid-r f-aid pos-time answer-time f-pening']/text()").toString();//logger.info("推荐时间:"+answerTime);//最佳回答点赞数String pointPraise =html.xpath("//span[@alog-action='qb-zan-btnbestbox']").toString();if(pointPraise!=null) {pointPraise = pointPraise.substring(pointPraise.lastIndexOf("evaluate")).replaceAll("evaluate=\"", "").replaceAll("\"> </span>", "");}//logger.info("最佳回答点赞数:"+pointPraise);//最佳回答拍砖数String contemptNumber =html.xpath("//span[@alog-action='qb-evaluate-outer']").toString();if(contemptNumber!=null) {contemptNumber = contemptNumber.substring(contemptNumber.lastIndexOf("evaluate")).replaceAll("evaluate=\"", "").replaceAll("\"> </span>", "");}//logger.info("最佳回答拍砖数:"+contemptNumber);//将发布时间和问题放到一块去,这里需要匹配String quizTimes = null;//这个判断有漏洞的!!!if(problem!=null) {for (int i = 0; i < lists.size(); i++) {String portionProblem = lists.get(i).get("portionProblems");String time = lists.get(i).get("quizTimes");boolean isThisProblem = true;for (int j = 0; j < portionProblem.length(); j++) {if(problem.indexOf(portionProblem.charAt(j))==-1){isThisProblem = false;}}if(isThisProblem){quizTimes = time;continue;}}}//发表时间//logger.info("发表时间:"+quizTimes);//其他回答答案List<String> otherAnswers =html.xpath("//div[@class='answer-text']/span").all();//logger.info("其他回答答案:"+otherAnswers);//其他回答的回答时间List<String> otherAnswerTime =html.xpath("//div[@class='grid pt-5']/span[@class='pos-time']/text()").all();//logger.info("其他回答的回答时间:"+otherAnswerTime);//其他回答的回答者List<String> otherAnswerAnthors =html.xpath("//a[@alog-action='qb-username' and @class='user-name']/text()").all();//logger.info("其他回答的回答者:"+otherAnswerAnthors);//其他回答的回答者等级List<String> otherAnswerAnthorGradesLists =html.xpath("//div[@class='grid pt-5']/span[@class='i-gradeIndex']").all();List<String> otherAnswerAnthorGrades = new ArrayList<String>();if(otherAnswerAnthorGradesLists!=null){for(int i=0;i<otherAnswerAnthorGradesLists.size();i++){otherAnswerAnthorGrades.add("LV"+otherAnswerAnthorGradesLists.get(i).substring(otherAnswerAnthorGradesLists.get(i).lastIndexOf("Index-")+6,otherAnswerAnthorGradesLists.get(i).lastIndexOf("\"></span>")));}}//logger.info("其他回答的回答者等级:"+otherAnswerAnthorGrades);//其他回答的点赞数List<String> otherAnswerPointPraiseLists =html.xpath("//span[@alog-action='qb-zan-btn']").all();List<String> otherAnswerPointPraises = new ArrayList<String>();if(otherAnswerPointPraiseLists!=null) {for(int i=0;i<otherAnswerPointPraiseLists.size();i++) {otherAnswerPointPraises.add(otherAnswerPointPraiseLists.get(i).substring(otherAnswerPointPraiseLists.get(i).lastIndexOf("evaluate")).replaceAll("evaluate=\"", "").replaceAll("\"> </span>", ""));}}//logger.info("其他回答的点赞数:"+otherAnswerPointPraises);//其他回答的拍砖数List<String> otherAnswerContemptNumberLists =html.xpath("//div[@class='pos-relative']/div[@class='qb-zan-eva']/span[@alog-action='qb-evaluate-outer']").all();List<String> otherAnswerContemptNumbers = new ArrayList<String>();if(otherAnswerContemptNumberLists!=null) {for(int i=0;i<otherAnswerContemptNumberLists.size();i++) {otherAnswerContemptNumbers.add( otherAnswerContemptNumberLists.get(i).substring(otherAnswerContemptNumberLists.get(i).lastIndexOf("evaluate")).replaceAll("evaluate=\"", "").replaceAll("\"> </span>", ""));}}//logger.info("其他回答的拍砖数:"+otherAnswerContemptNumbers);//如果为了效率,可以开线程去存数据的if(answerAuthor!=null || otherAnswers.size()!=0){//问题表数据Problem p = new Problem();String problemId = cn.hncu.tool.UUID.getId();p.setId(problemId);p.setProblem(problem);p.setQuizTime(quizTimes);p.setProblemAnthor(problemAnthor);p.setProblemDescribe(problemDescribe);//关键字—问题关系表数据KeywordProblemKey keywordProblemKey = new KeywordProblemKey();keywordProblemKey.setKeywordId(keywordId);keywordProblemKey.setProblemId(problemId);//最佳答案数据List<Answer> answers = new ArrayList<Answer>();Answer answer = new Answer();answer.setId(cn.hncu.tool.UUID.getId());answer.setProblemId(problemId);answer.setAnswerAnthor(answerAuthor);answer.setAnswer(bestAnswer);answer.setAnthorGrade(anthorGrade);answer.setPointPraise(pointPraise);answer.setAnswerTime(answerTime);answer.setContemptNumber(contemptNumber);answers.add(answer);//其他答案数据Integer otherAnswersSize = otherAnswers.size();for(int i=0;i<otherAnswersSize;i++){answer = new Answer();answer.setId(cn.hncu.tool.UUID.getId());answer.setProblemId(problemId);if(otherAnswerAnthors.size()>i)answer.setAnswerAnthor(otherAnswerAnthors.get(i));if(otherAnswers.size()>i)answer.setAnswer(otherAnswers.get(i));if(otherAnswerAnthorGrades.size()>i)answer.setAnthorGrade(otherAnswerAnthorGrades.get(i));if(otherAnswerPointPraises.size()>i)answer.setPointPraise(otherAnswerPointPraises.get(i));if(otherAnswerTime.size()>i)answer.setAnswerTime(otherAnswerTime.get(i));if(otherAnswerContemptNumbers.size()>i)answer.setContemptNumber(otherAnswerContemptNumbers.get(i));answers.add(answer);}keywordService.insertAll(p,keywordProblemKey,answers);}
//        if (page.getResultItems().get("name") == null) {
//            //skip this page
//            page.setSkip(true);
//        }// 从搜索页面发现后续的url地址来抓取
//        List<String> urls = html.links().regex("(http://zhidao.baidu.com/question/.+"+"\\?"+".+[^\"])").all();
//        for(String url:urls){
//            logger.info(url);
//        }if(problem==null) {page.addTargetRequests(html.links().regex("(http://zhidao.baidu.com/question/.+"+"\\?"+".+[^\"])").all());for(int i=1;i<pages;i++){List<String> lists = new ArrayList<String>();lists.add(url+keyword+"&site=-1&sites=0&date=0&pn="+(i*10));page.addTargetRequests(lists);}pages=0;//只加一次进队列!}}@Overridepublic Site getSite() {return site;}public static void main(String[] args) throws IOException {//使用"spring.xml"和"spring-mybatis.xml"这两个配置文件创建Spring上下文context = new ClassPathXmlApplicationContext("spring.xml", "spring-mybatis.xml");keywordService = (KeywordService) context.getBean("keywordService");//存储关键字表Date searchTime = new Date();//搜索的时间keywordId = cn.hncu.tool.UUID.getId();Keyword keyword = new Keyword();keyword.setId(keywordId);keyword.setKeyword(Entrance.keyword);keyword.setSearchTime(searchTime);keywordService.insertKeyword(keyword);Spider.create(new Entrance()).addUrl(url+Entrance.keyword)//.addPipeline(new JsonFilePipeline("D:\\test\\"))//开启 *个线程抓取.thread(50)//同步启动爬虫.run();}
}

数据库很简单,看你自己需要哪些数据,就建立哪些字段和表就行。

建立MySQL数据表的文件在项目的src/main/resources/sql/1.sql

本篇博客涉及到的源码链接:

【->点击访问源码-©CHX】


本文章由[谙忆]编写, 所有权利保留。
欢迎转载,分享是进步的源泉。

转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自【大学之旅_谙忆的博客】

【网络爬虫】给关键字获取百度知道搜索数据的网络爬虫相关推荐

  1. 从零开始写Python爬虫 --- 1.5 爬虫实践: 获取百度贴吧内容

    从零开始写Python爬虫 --- 1.5 爬虫实践: 获取百度贴吧内容 Ehco 5 个月前 经过前期大量的学习与准备,我们重要要开始写第一个真正意义上的爬虫了.本次我们要爬取的网站是:百度贴吧,一 ...

  2. 企业网络推广时网站获取排名离不开企业网络推广文章内容的更新

    搜索引擎在抓取网站排名时,网站内容价值性的体现瞬间放大,与此同时,网站内容更新频率也是不容小觑的.对于企业网站运营优化期间,不同类型的企业网站可以选择不同的内容更新频率,那么怎样针对企业网站制定合理的 ...

  3. 【爬虫】Python2爬虫代码之获取金融品种行情数据

    Python2爬虫代码之获取金融品种行情数据 #!/usr/bin/env python # -*- coding: utf-8 -*- import requests #使用requests包方便 ...

  4. python 爬虫 获取bilibili search搜索数据,返回json格式

    话不多说直接上代码 测试用例 : 搜索java为关键词的 时长在60分钟以上的视频 import requests import json import osheaders = {"user ...

  5. 百度头条改版了?发一个最新获取百度头条新闻数据

    百度热点新闻改版导致获取失效了,重新写了一版 , 注意是热点榜数据 <?php //获取百度热点榜新闻 header('content-type:application/json'); echo ...

  6. 学习记录:python GoPUP获取百度指数动态数据对比看国人野性消费

    前言 前几天看公众号,看到一篇文章利用GoPUP获取百度指数,做鸿星尔克崛起的数据对比感觉挺有意思的,参考一下文章也来玩玩学习学习 原文:http删除我s://m删除我p.we删除我ixin.q删除我 ...

  7. Python爬虫实践: 获取百度贴吧内容

    最近开始整理python的资料,博主建立了一个qq群,希望给大家提供一个交流的平台 78486745 . 我们要爬取的网站是:百度贴吧,一个非常适合新人练手的地方,那么让我们开始吧. 本次要爬的贴吧是 ...

  8. 【爬虫】爬取百度贴吧数据

    在这里我们写一个简单的小爬虫程序,爬取百度贴吧前几页的数据. import requests import sysclass Tieba(object): def __init__(self, nam ...

  9. 【爬虫实践】获取某城市天气数据

    功能需求 获取山东济南城市每天的天气情况. 需要获取四个数据:天气.温度.风向.风级. url地址:http://www.weather.com.cn/weather/101120101.shtml ...

最新文章

  1. Why平台:Scalable是互联网公司的价值所在
  2. Java IO: Buffered和Data
  3. 成功解决AttributeError: module tensorflow.sets has no attribute intersection
  4. ajax请求php的过程,php如何实现ajax请求
  5. VS2005水晶报表发布
  6. 反射调用 java bean的set和get方法
  7. Apache JK Tomcat 集群问题
  8. php validator classes
  9. Anroid camera + mediacodec
  10. 广数系统980tdb系统说明书_不同数控系统中各个倒角指令的用法
  11. 通信原理第七版樊昌信 课后习题答案详解
  12. python评分卡模型
  13. php编程怎样装数据库,php数据库管理工具phpmyadmin下载、安装、配置
  14. 百果园港交所上市:市值近百亿港元 80%营收来自加盟店
  15. ZiSync:跨平台局域网自同步工具
  16. linux的日志处理之Logrotate
  17. C#读取txt日志文件
  18. 为响应国家减税,SAP增值税如何调整 ?
  19. 如何在Adobe Illustrator中创建青蛙王子插图
  20. 3ds Max 2024新特性及安装图文教程

热门文章

  1. 揭秘搜狗手机浏览器测试高效管理方法(一)
  2. 成年人需要学会持续性学习
  3. Web开发者不容错过的20段CSS代码
  4. 12月9号(第36天的学习
  5. Vision and Art ,The Biology of Seeing 读书笔记
  6. 将Ext JS 5应用程序导入Web项目中
  7. 简易抽奖系统——java实现
  8. 前端与后端,顶象设备指纹的两种接入方式
  9. sklearn.linear_model之LinearRegression核心源码解析
  10. 雷鸟邮件客户端(Thunderbird)安装教程篇