需求:
给定若干个关键字将关键字依次搜索,将所有关键字搜索到的微博信息,存入到仓库。
本程序是在webcollector的基础上改动的。程序中有详细的解释。
步骤:
1,设置微博用户登录。
2,找到一个搜索的入口网站,最后一页,这样就不会爬不相干的内容了。在构造方法中创建。
3,添加二级搜索目标文件,这里才是真正需要搜索的数据,在visit方法中添加。
4,visit方法,每次翻页或是更新了地址都会调用它,每页的数据就是在这个方法中取的。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;
import org.springframework.jdbc.core.JdbcTemplate;
import com.yao.crawler.sina.bean.WebContext;
import com.yao.dao.JDBCHelper;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.net.HttpRequest;
import cn.edu.hfut.dmic.webcollector.net.HttpResponse;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
/**
* 爬取新浪微博的内容;
* 注意要是进入到爬取过的页面,程序会自动停止
* @author yao
*/
public class WebSeachContextDepthCrawler4 extends BreadthCrawler{
static List<WebContext> WebContextList=new ArrayList<WebContext>();
String cookie;
static JdbcTemplate jdbcTemplate = null;
static{//静态块连接数据库
try {
jdbcTemplate = JDBCHelper.createMysqlTemplate("mysql1",
"jdbc:mysql://localhost:3306/progrart?useUnicode=true&characterEncoding=utf8",
"root", "a", 5, 30);
} catch (Exception ex) {
jdbcTemplate = null;
System.out.println("mysql未开启或JDBCHelper.createMysqlTemplate中参数配置不正确!");
}
}
//public int startpage=1;
public int startpage=0;//设置起始页,因为后面的++在前面所以可以将其设为0
private String url;//访问的地址
private String kw;//除第一次访问的地址
//存储需要搜索的目标的list
static List<String> listkwordst=new ArrayList<String>();
private boolean falgf=false;//判断是否为入口查询,过滤
//将地址和页面数设置为地址栏的编码
public static String createBingUrl(String keyword, int pageNum) throws Exception {
int first = pageNum;// * 10 - 9;
keyword = URLEncoder.encode(keyword, "utf-8");
//return String.format("http://cn.bing.com/search?q=%s&first=%s", keyword, first);
return String.format("http://weibo.cn/search/mblog?hideSearchFrame=&keyword=%s&page=%s&vt=4", keyword, first);
}
public WebSeachContextDepthCrawler4(String crawlPath, boolean autoParse,String keyword) throws Exception {
super(crawlPath, autoParse);
cookie = WeiboCN.getSinaCookie("微博用户名", "密码");
url = createBingUrl(keyword,76);//76是因为这页就已经没有内容了,只需它提供一个入口
//System.out.println("--WebSeachContextDepthCrawler4---url==========="+url);
CrawlDatum datum = new CrawlDatum(url)
.meta("keyword", keyword)
.meta("pageNum", 1 + "")
.meta("pageType", "searchEngine")
.meta("depth", "1");
addSeed(datum);
}
@Override
public HttpResponse getResponse(CrawlDatum crawlDatum) throws Exception {
HttpRequest request = new HttpRequest(crawlDatum);
request.setCookie(cookie);
return request.getResponse();
}
@Override
public void visit(Page page, CrawlDatums next) {
//System.out.println("----pageurl----"+page.getUrl());
int text1=page.doc().select("div[class=c]").size();
//System.out.println("****text1****"+text1);
String url1=page.getUrl();
if(text1<=6){//判断当前页面是否还有内容
//System.out.println("-----小于5来了-----");
startpage=1;
String url5="http://weibo.cn/search/mblog?hideSearchFrame=&keyword=";
if(listkwordst.size()>0){//判断存的目标字段,是否还有,没有就结束程序
System.out.println("******listkwordst.size()******"+listkwordst.size());
if(falgf){//判断是否是滴一次执行程序,第一次不要移除
String stt=listkwordst.remove(0);
}
String stt1=listkwordst.get(0);
try {
kw=URLEncoder.encode(stt1, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String url6=url5+kw+"&page="+startpage+"&vt=4";
//System.out.println(stt1+"****小于5de ------"+url6);
//System.out.println("---"+startpage+"---url==========="+url);
CrawlDatum datum = new CrawlDatum(url6)
.meta("depth", "1");
next.add(datum);
}
}else{
startpage++;
String url2=url1.substring(0,url1.lastIndexOf("e")+1);
String url3=url2+"="+startpage+"&vt=4";
//System.out.println("---"+startpage+"---url1==========="+url1);
//System.out.println("***"+startpage+"***url3==========="+url3);
//随机休眠1到2秒,放在封号
int x=1+(int)(Math.random()*2);
x=x*1000;
try {
//System.out.println("开始等待");
Thread.sleep(x);
// System.out.println("等待完成");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
CrawlDatum datum = new CrawlDatum(url3)
.meta("depth", "1000")
.meta("referer", url3);
next.add(datum);
if(falgf){//判断是否为程序入口
getWebUserInfo(page, next,listkwordst.get(0));
}else{
falgf=true;
}
}
}
@Override
protected void afterParse(Page page, CrawlDatums next) {
//当前页面的depth为x,则从当前页面解析的后续任务的depth为x+1
int depth;
//如果在添加种子时忘记添加depth信息,可以通过这种方式保证程序不出错
if(page.meta("depth")==null){
depth=1;
}else{
depth=Integer.valueOf(page.meta("depth"));
}
depth++;
for(CrawlDatum datum:next){
datum.meta("depth", depth+"");
}
}
/**
* 删除内容中的a标签
* @param content
*/
private String removeContentAlink(String con) {
String content = con;
if(content.matches(".*<a +[^>]*>.*</a>.*")){
content = content.substring(0,content.indexOf("<a"))+content.substring(content.indexOf("</a>")+4);
content = removeContentAlink(content);
}
return content;
}
public void getWebUserInfo(Page page, CrawlDatums next, String LABEL){
String WBUID=null;//用户id
String WBUSER=null;//用户昵称
String CONTENT=null;//内容/转发理由
String PRAISE=null;//赞
String REPOST=null;//转发
String WBCOMMENT=null;//评论
String REPORTPRAISE=null;//原文的赞
String ORIGINREPOST=null;//原文转发
String ORIGINCOMMENT=null;//原文评论
String HTML=null;//原文内容
String PLATFORM=null;//平台
String PUBLISHED=null;//发布时间
String TRANSIMT="0";//是否为转发微博
//取到页面所有的div元素
Elements aa1=(Elements) page.doc().select("div[class=c]");
for(Element e:aa1){//循环每个元素
//判断非转发微博,且不含图片"
// System.out.println("--e=="+e.text());
if(e.select("div").size()==2&&e.select("div").select("a").size()>4){
// System.out.println(e.select("div").html());
WBUID=e.select("a[class=nk]").attr("href");//访问用户的id
WBUSER=e.select("a[class=nk]").first().text();//用户昵称
//System.out.println("---"+WBUID+"==="+WBUSER);
//outerHtml 取到包含该元素的标签 Html则只包含下一级
String htm=e.select("div span[class=ctt]").get(0).outerHtml();
// System.out.println("------");
String hh=removeContentAlink(htm);
// System.out.println(hh);
// System.out.println("********");
// CONTENT=e.select("div").select("span[class=ctt]").text();//内容
Element spa=e.select("div span[class=ctt]").first();
Element ss=new Element(spa.tag(), "");//将字符串转为元素
ss.append(hh);//注意字符只能由append添加
CONTENT=ss.text();//内容
// System.out.println(hh+"********ssss8***8****"+ss.outerHtml());
// System.out.println("_______________"+CONTENT);
int flaga=e.select("div").eq(1).select("span[class=ct]").select("a").size();
// System.out.println("flaga==="+flaga);
if(flaga==0){
int index=e.select("div").eq(1).select("a").size();
String zan=e.select("div").eq(1).select("a").eq(index-4).text();
//赞
PRAISE=getNumber(zan);
//System.out.print("==="+WBUSER+"--赞--"+PRAISE);
String zhaung=e.select("div").select("a").eq(index-3).text();
//转发
REPOST=getNumber(zhaung);
// System.out.print("--转--"+REPOST);
String ping=e.select("div").select("a").eq(index-2).text();
//评论
WBCOMMENT=getNumber(ping);
// System.out.print("--评--"+WBCOMMENT);
// System.out.println();
}else{
int index=e.select("div").eq(1).select("a").size();
String zan=e.select("div").eq(1).select("a").eq(index-5).text();
//赞
PRAISE=getNumber(zan);
//System.out.print("==="+WBUSER+"--赞--"+PRAISE);
String zhaung=e.select("div").select("a").eq(index-4).text();
//转发
REPOST=getNumber(zhaung);
// System.out.print("--转--"+REPOST);
String ping=e.select("div").select("a").eq(index-3).text();
//评论
WBCOMMENT=getNumber(ping);
// System.out.print("--评--"+WBCOMMENT);
// System.out.println();
}
String timeandplatform=e.select("div").select("span[class=ct]").text();
//System.out.println("==="+WBUSER+"******"+timeandplatform);
//平台
PLATFORM=getPlatform(timeandplatform);
//时间
PUBLISHED=getTime(timeandplatform);
// System.out.println(WBUSER+"==="+PLATFORM+"----"+PUBLISHED);
if (jdbcTemplate != null) {
int updates=jdbcTemplate.update("insert into WebSeachContextDepthCrawler"
+" values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
WBUID, WBUSER, CONTENT,PRAISE,REPOST,WBCOMMENT,REPORTPRAISE,ORIGINREPOST,
ORIGINCOMMENT,HTML,PLATFORM,PUBLISHED,TRANSIMT,LABEL);
if(updates==1){
System.out.println("*******mysql插入成功******");
}else{
System.out.println("-----mysql插入失败--------");
}
}
}else if(e.select("div").size()==3){
// System.out.println(e.select("div").html());
WBUID=e.select("a[class=nk]").attr("href");//访问用户的id
WBUSER=e.select("a[class=nk]").first().text();//用户昵称
//System.out.println("---"+WBUID+"==="+WBUSER);
//System.out.println("---"+WBUID+"==="+WBUSER);
String hh=removeContentAlink(e.select("div").eq(1).select("span[class=ctt]").first().html());
Element span=e.select("div").eq(1).select("span[class=ctt]").first();
Element ss=new Element(span.tag(),"");
ss.append(hh);
CONTENT=ss.text();//内容
// System.out.println("==="+WBUSER+"----"+CONTENT);
int flaga=e.select("div").last().select("span[class=ct]").select("a").size();
if(flaga==0){
int index=e.select("div").last().select("a").size();
String zan=e.select("div").last().select("a").eq(index-4).text();
//System.out.println(WBUSER+"--赞--"+zan);
//赞
PRAISE=getNumber(zan);
//System.out.print("==="+WBUSER+"--赞--"+PRAISE);
String zhaung=e.select("div").last().select("a").eq(index-3).text();
//转发
REPOST=getNumber(zhaung);
// System.out.print("--转--"+REPOST);
String ping=e.select("div").last().select("a").eq(index-2).text();
//评论
WBCOMMENT=getNumber(ping);
// System.out.print("--评--"+WBCOMMENT);
// System.out.println();
}else{
int index=e.select("div").last().select("a").size();
String zan=e.select("div").last().select("a").eq(index-5).text();
//System.out.println(WBUSER+"--赞--"+zan);
//赞
PRAISE=getNumber(zan);
//System.out.print("==="+WBUSER+"--赞--"+PRAISE);
String zhaung=e.select("div").last().select("a").eq(index-4).text();
//转发
REPOST=getNumber(zhaung);
// System.out.print("--转--"+REPOST);
String ping=e.select("div").last().select("a").eq(index-3).text();
//评论
WBCOMMENT=getNumber(ping);
// System.out.print("--评--"+WBCOMMENT);
// System.o
}
String timeandplatform=e.select("div").last().select("span[class=ct]").text();
// System.out.println("==="+WBUSER+"******"+timeandplatform);
//平台
PLATFORM=getPlatform(timeandplatform);
//时间
PUBLISHED=getTime(timeandplatform);
//System.out.println(WBUSER+"==="+PLATFORM+"----"+PUBLISHED);
if (jdbcTemplate != null) {
int updates=jdbcTemplate.update("insert into WebSeachContextDepthCrawler"
+" values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
WBUID, WBUSER, CONTENT,PRAISE,REPOST,WBCOMMENT,REPORTPRAISE,ORIGINREPOST,
ORIGINCOMMENT,HTML,PLATFORM,PUBLISHED,TRANSIMT,LABEL);
if(updates==1){
System.out.println("*******mysql插入成功******");
}else{
System.out.println("-----mysql插入失败--------");
}
}
}else if(e.select("div").size()==4){
TRANSIMT="1";
// System.out.println(e.select("div").html());
WBUID=e.select("div").eq(1).select("a[class=nk]").attr("href");//访问用户的id
WBUSER=e.select("div").eq(1).select("a[class=nk]").first().text();//用户昵称
// System.out.println("---"+WBUID+"==="+WBUSER);
HTML=removeContentAlink(e.select("div").eq(1).select("span[class=ctt]").html());//原文内容
//System.out.println("==="+WBUSER+"----"+HTML);
String yuzan=e.select("div").eq(2).select("span[class=cmt]").first().text();
//System.out.println("==="+WBUSER+"----"+yuzan);
REPORTPRAISE=getNumber(yuzan);//原文赞
String yuzhuang=e.select("div").eq(2).select("span[class=cmt]").last().text();
ORIGINREPOST=getNumber(yuzhuang);//原文转发
String yupinglun=e.select("div").eq(2).select("a[class=cc]").text();
ORIGINCOMMENT=getNumber(yupinglun);//原文评论
/*System.out.println("==="+WBUSER+"--赞--"+REPORTPRAISE+
"--转发--"+ORIGINREPOST+"--评论--"+ORIGINCOMMENT);*/
String context=e.select("div").last().text();//内容
CONTENT=context.substring(0,context.indexOf(" "));//转发理由,原文
//System.out.println("==="+WBUSER+"----"+CONTENT);
String text4=e.select("div").last().select("a").text();
// System.out.println(WBUID+"--suoyou---"+text4);
PRAISE=text4.substring(text4.indexOf("赞")+2,text4.indexOf("]"));//赞
//System.out.print(WBUID+"--zan---"+PRAISE);
String zhuan=text4.substring(text4.indexOf("]")+1);
//System.out.print("zhuan==="+zhuan);
REPOST=zhuan.substring(zhuan.indexOf("发")+2,zhuan.indexOf("]"));//转发
// System.out.print("--zhuang---"+REPOST);
String pinglun=zhuan.substring(zhuan.indexOf("]")+1);
WBCOMMENT=pinglun.substring(pinglun.indexOf("论")+2, pinglun.indexOf("]"));//评论
// System.out.print("--评论---"+WBCOMMENT);
//System.out.println();
String timeandplatform=e.select("div").last().select("span[class=ct]").text();
//System.out.println("==="+WBUSER+"******"+timeandplatform);
//平台
PLATFORM=getPlatform(timeandplatform);
//时间
PUBLISHED=getTime(timeandplatform);
//System.out.println(WBUSER+"==="+PLATFORM+"----"+PUBLISHED);
if (jdbcTemplate != null) {
int updates=jdbcTemplate.update("insert into WebSeachContextDepthCrawler"
+" values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
WBUID, WBUSER, CONTENT,PRAISE,REPOST,WBCOMMENT,REPORTPRAISE,ORIGINREPOST,
ORIGINCOMMENT,HTML,PLATFORM,PUBLISHED,TRANSIMT,LABEL);
if(updates==1){
System.out.println("*******mysql插入成功******");
}else{
System.out.println("-----mysql插入失败--------");
}
}
}
}
}
//得到时间
private String getTime(String st){
if(st.indexOf("来")>0){
return st.substring(0,st.indexOf("来"));
}else{
return st.substring(0);
}
}
//得到平台
private String getPlatform(String st){
if(st.indexOf("来")>0){
return st.substring(st.indexOf("来"));
}else{
return null;
}
}
//得到评论数,赞数,转发数
private String getNumber(String st){
return st.substring(st.indexOf("[")+1,st.indexOf("]"));
}
public static void main(String[] args) throws Exception {
String filePath = "F:/1/tra.csv";//目标文件路径
readTxtFile(filePath);//将文件添加到list
WebSeachContextDepthCrawler4 crawler=
//第一个数,表示爬取页数
//第二个数,表示起始页
new WebSeachContextDepthCrawler4("depth_crawler",true,"美的制冷");
crawler.start(1000000000);//注意这里深度尽量要设置大些,过小可能不能遍历完目标数据
//每一次访问就是深度加一
}
//读取文件方法
public static void readTxtFile(String filePath) {
try {
String encoding = "GBK";//编码格式
File file = new File(filePath);//读入文件
if (file.isFile() && file.exists()) { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);//读入文件
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
listkwordst.add(lineTxt);//将文件添加到list
//System.out.println(lineTxt);
}
read.close();
} else {
System.out.println("找不到指定的文件");
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
}
}
}