php抓取网页不全 js(先看一下新浪微博搜索结果页面的源码:项目源码已经整理)
优采云 发布时间: 2022-02-14 23:08php抓取网页不全 js(先看一下新浪微博搜索结果页面的源码:项目源码已经整理)
这个文章爬取使用jsoup,在需求简单的时候比httpclient方便很多。有指导意义,但不太适合我的需求,比如没有登录。
项目需要抓取新浪微博的搜索结果数据,制作一个工具,自动抓取新浪微博搜索中配置的关键词的搜索结果。在这里分享。
我们来看一下新浪微博搜索结果页面的源码:
可以看出,得到的不是普通的html,而是通过js调用的。汉字都是编码的。所有文本元素都采用上面红框中的格式。要得到搜索结果,需要对红框中的文字进行解析。用到了jsoup和fastjson这两个jar包,需要自己下载。
汤:
快速json:
搜索结果爬取核心类:
<p>
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.solr.common.SolrInputDocument;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.safety.Whitelist;
import org.jsoup.select.Elements;
import com.alibaba.fastjson.JSON;
public class WeiboFetcher extends AbstractFetcher {
// 文本块正文匹配正则
private final String blockRegex = "STK\\s&&\\sSTK\\.pageletM\\s&&\\sSTK\\.pageletM\\.view\\(.*\\)";
private Pattern pattern = Pattern.compile(blockRegex);
private static Whitelist whitelist = new Whitelist();
static{
// 只保留em标签的文本
whitelist.addTags("em");
}
@Override()
public List fetch() {
List newsResults = new ArrayList();
newsResults = WeiboResult();
System.out.println("WeiboFetcher Over: " + newsResults.size());
return newsResults;
}
/**
* 获取关键字搜索结果
* @return
*/
private List WeiboResult() {
String keyWord = null;
List newsResultList = new ArrayList();
// 获取配置的关键字
List keyWordList = KeywordReader.getInstance().getKeywords();
for (String keyWordLine : keyWordList) {
// 转换为新浪微博搜索接受的格式
keyWord = policy.getKeyWord(keyWordLine,null);
newsResultList.addAll(getWeiboContent(keyWord));
}
return newsResultList;
}
/**
* 获取搜索结果
* @param keyWord
* @return
*/
private List getWeiboContent(String keyWord){
System.out.println("fetch keyword: " + keyWord);
List resultList = new ArrayList();
for(int i = 0; i 0){
page = "&page=" + (i+1);
}
//抓取返回50个内容
try {
System.out.println("fetch url page depth " + (i + 1));
// 注意&nodup=1
Document doc = Jsoup.connect(
"http://s.weibo.com/weibo/" + keyWord+"&nodup=1" + page).get();
String source = doc.html();
// 匹配文本块
Matcher m = pattern.matcher(source);
while(m.find()){
String jsonStr = m.group();
jsonStr = jsonStr.substring(jsonStr.indexOf("{"), jsonStr.lastIndexOf(")"));
// 解析json,转换为实体类
WeiboBlock block = JSON.parseObject(jsonStr, WeiboBlock.class);
if(block.getHtml().trim().startsWith("")){
doc = Jsoup.parse(block.getHtml());
}
}
List elements = getAllElement(doc);
if(elements == null || elements.size() == 0){
System.out.println("No more urls to fetch with current keyword." );
return resultList;
}
for (Element elem : elements) {
String url = elem.select(".date").last().attr("href");
String dateS = elem.select(".date").last().attr("date");
String content = null;
Date date = null;
String content_text = null;
String title = null;
if (!isCrawledUrl(url)){
if (url != null) {
if (dateS != null && !"".equals(dateS)) {
try {
date = sdf.parse(changeString2Date(dateS));
} catch (ParseException e) {
e.printStackTrace();
}
}
if (date != null) {
elem.getElementsByClass("info W_linkb W_textb").remove();
content = Jsoup.clean(Jsoup.clean(elem.select(".content").html(), whitelist), Whitelist.none());
title = this.parseTitle(content);
url = elem.select(".date").last().attr("href");
SolrInputDocument sid = buildSolrInputDocumentList(url, content, title, date);
if (sid != null && sid.size() > 0) {
resultList.add(sid);
}
}
}else {
System.out.println("current Url: ---------null------------" );
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
return resultList;
}
/**
* 获取所有的结果正文节点
* @param doc
* @return
*/
private List getAllElement(Document doc) {
List resultList = new ArrayList();
Elements elems = doc.select(".search_feed .feed_list");
for (Element element : elems) {
resultList.add(element);
}
return resultList;
}
@Override
protected boolean isCrawledUrl(String url) {
return isAvaliableUrl(url);
}
/**
* 生成标题
* @param htmlContent
* @return
*/
private String parseTitle(String htmlContent) {
if (htmlContent == null || htmlContent.trim().equals(""))
return null;
String title = htmlContent;
title = title.trim();
for (int i = 0; i