前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java爬虫(3)——拼接url抓取“加载更多”内容

Java爬虫(3)——拼接url抓取“加载更多”内容

作者头像
一头小山猪
发布2020-04-10 10:56:17
1.5K0
发布2020-04-10 10:56:17
举报
文章被收录于专栏:微光点亮星辰

上期我们说到phantomjs可模拟点击按钮行为,通过点击完所有”加载更多”按钮来抓所有内容。比如这个网页http://e.vnexpress.net/news/news

我们要抓取红线所标注的超链接,将url入库,点击“view more stories”会出现更多列表,然而有些网页是,点到所有隐藏内容都出现后,那个“view more stories”按钮还是存在,给判断模拟点击行为何时终止造成困难。或许聪明的朋友会说:“有什么困难的?模拟一次点击行为,抓取一次网页,从下至上获取列表项的url,当url与数据库中已经抓取的url重复时,停止获取。当从下至上获取的第一个url就与数据库中的url重复时,说明已经获取整张网页的所有内容,可停止模拟点击行为……“。这的确是个办法,但存在着大量判断和对网页的重复抓取,我们有个更优雅的解决方式,何乐而不为呢??(另外真要模拟的话selenium比phantomjs更稳定的…)

想必大家通过标题就已经知道接下来我要说的所谓的更优雅的方式是什么了吧……没错!拼接url。

打开控制台的network模块,

点击“view more stories”按钮,出现以下网络请求,注意这个type为xhr的网络请求,这正是向后台请求更多列表项的。观察请求头,

请求的参数有两个,于是尝试拼接url如下

http://e.vnexpress.net/news/news?cate_id=1003894&page=4

得到了13个列表项,但是点击加载更多按钮,新增的却是15个,也只是少了两个列表项,不怎么影响整体抓的效果,就采用此方式来抓了,拼到什么时候为止呢??当page参数大于实际最大页数时,有的网页是不出现“view more stories”按钮,有的仍然出现按钮,但显示的都是最大页数那一页的内容。根据不同情况来判断是否停止抓取。

下面来贴代码:(大部分基础代码已在前文解释过,就不赘述了)

代码语言:javascript
复制
package edu.nju.opsource.vnexpress.linktype;
import java.io.InputStream;
import java.util.Date;
import java.util.LinkedList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.onezetta.downloader.EasyHttpDownloader;
import edu.nju.opensource.common.beans.ELinkState;
import edu.nju.opensource.common.beans.Link;
import edu.nju.opensource.common.beans.LinkType;
import edu.nju.opensource.common.beans.Site;
import edu.nju.opsource.vnexpress.utils.IdXmlUtil;
public class LinkType_NewsList extends LinkType {
private Document doc = null;
private Site site = null;
private LinkedList<Link> newItems = null;
private Link nextPage = null;
public LinkType_NewsList() {
super();
// TODO Auto-generated constructor stub
}
public LinkType_NewsList(String linkTypeName) {
super.setLinkTypeName(linkTypeName);
}
public LinkType_NewsList(Site site) {
super.setLinkTypeName("vnexpress.newslist");
this.site = site;
}
public void get(String url) {
super.get(url);
String content = new EasyHttpDownloader(url).run();
if (content != null) {
this.doc = Jsoup.parse(content, this.site.getUrl().getUrl());
System.out.println(" ... has Crawled.");
} else {
setState(ELinkState.CRAWLFAILED);
System.out.println(" ... crawled failed.");
}
}
// 把新闻列表条目的链接插入表
// 在总项目中被调用的核心函数handle()
@Override
public boolean handle(Link parentlink) throws Exception {
if (getState() == ELinkState.CRAWLFAILED)
return false;
Elements news = this.doc.select("div.list_news_folder.col_720 h4.title_news_site");
this.newItems = new LinkedList();
boolean flag = false;
for (Element newItem : news) {
Elements tmp = newItem.select("a");
if ((tmp != null) && (tmp.size() != 0)) {
Link link = new Link(tmp.first().attr("abs:href"), new LinkType_News(), ELinkState.UNCRAWL, parentlink,
this.site).setLinkDate( new java.sql.Date(new Date().getTime()));
// System.out.println(tmp.first().attr("abs:href"));
int rst = link.insert();
if (rst == -1)
flag = true;// link exist
}
}
if (flag) {
setState(ELinkState.CRAWLED);
return false;
}
Elements nextPageE = this.doc.select("a#vnexpress_folder_load_more");
           String url = getNextPageUrl();
if ((nextPageE != null) && (nextPageE.size() != 0)) {
System.out.println(url);
this.nextPage = new Link(url, new LinkType_NewsList(this.site), ELinkState.UNCRAWL, parentlink, this.site).setLinkDate( new java.sql.Date(new Date().getTime()));
this.nextPage.insert();
}
else {
IdXmlUtil.setIdByName("news", 2 + "");
}
setState(ELinkState.CRAWLED);
return true;
}
public static String getNextPageUrl() {
int id = IdXmlUtil.getIdByName("news");
// IdXmlUtil用来存储当前已抓取的pageid其实这个工具完全没必要,因为数据库的//url有此参数啊。。。当时脑抽没想到,搞麻烦了。。。
IdXmlUtil.setIdByName("news", (id + 1) + "");
//此文章的精髓
String url = "http://e.vnexpress.net/news/news?cate_id=1003894&page=" + id;
return url;
}
@Override
public String getLinkTextData() {
// TODO Auto-generated method stub
return null;
}
@Override
public InputStream getLinkBinaryData() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getLinkUniqeID(String paramString) {
// TODO Auto-generated method stub
return null;
}
@Override
public Date getLinkDate() {
// TODO Auto-generated method stub
return null;
}
public Site getSite() {
return this.site;
}
@Override
public void setSite(Site site) {
// TODO Auto-generated method stub
this.site = site;
}
public LinkedList<Link> getNewItems() {
return this.newItems;
}
public void setNewItems(LinkedList<Link> newItems) {
this.newItems = newItems;
}
public Link getNextPage() {
return this.nextPage;
}
public void setNextPage(Link nextPage) {
this.nextPage = nextPage;
}
@Override
public String toString() {
return "LinkType_newsList [doc=" + doc + ", site=" + site + ", newItems=" + newItems + ", nextPage="
+ nextPage + "]";
}
}

本以为爬虫系列写到这儿就完结了的,其实还有个问题,就是我们在浏览器上试url来查看效果,然而有的网站以这种方式尝试看不到任何内容,这是因为浏览器输入网址是以get请求,有些网站的后台内容不接受get请求。这样的话,我们该怎样查看拼接url的效果呢???

期待下期吧 >0<

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微光点亮星辰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档