1. webmagic抓取URL原理
url形式多样,一个网页里包含的url 简单列举为以下情形:
1)绝对链接url, 形如https://i.csdn.net/#/uc/profile,返回为html网页。
2)相对url,如 " /etc/info/index.jsp ", 其完整网址需要和当前页面地址拼凑而来
3)动态js/ajax请求,如http://48.98.121.251:9000/iLamp/lampindex/rate,返回为json结果。
webmagic抓取当前页面url添加到后续队列语句:
page.addTargetRequests(page.getHtml().links().all());
那么 webmagic可以抓取全部格式的url吗?看page的getHtml方法,此方法先获得html页面,返回html对象
/** get html content of page
* @return html
*/
public Html getHtml() {
//如果html为空,说明返回的不是html文件,可能是ajax返回的json值,结果存放在rawText
if (html == null) {
html = new Html(UrlUtils.fixAllRelativeHrefs(rawText, request.getUrl()));
}
//如果不为空,则获得的页面为html网页
return html;
}
然后html.links(),Html继承自HtmlNode : public class Html extends HtmlNode
public class HtmlNode extends AbstractSelectable {
//links方法
@Override
public Selectable links() {
return xpath("//a/@href");
}
}
此处可以看出,webmagic本质上获取当前页链接,只是获得了格式为<a href="url">的url。
2.添加非标准url地址(需要自行添加)
2.1 相对url
正则匹配获得相对url /etc/info/index.jsp ,结合当前页拼凑完整url:http://48.50.192.121/etc/info/index.jsp 添加到targetRequest.
2.2 动态js/get方式Ajax请求
get方式ajax请求,可以直接把ajax请求的地址,添加到待处理队列。
page.addTargetRequest("http://48.90.120.241:9000/iLamp/mobile/device/weatherHefeng?cityNum=CN101190104");
2.3 动态js/post方式url
新建request,设置POST请求。
Request request=new Request("http://48.91.121.241:9000/iLamp/lampindex/rate");
request.setMethod(HttpConstant.Method.POST);
page.addTargetRequest(request);
动态url分析获取,可以调用chrome调试工具,network-response-xhr , 就可以看到浏览过程汇总访问的接口。
3 系统登录与Cookie获取
配置 selenium ,根据标签获得输入框和确定键,输入账户密码,点击登录。获得cookies
//使用 selenium 来模拟用户的登录获取cookie信息
public void login() {
WebDriver driver = new ChromeDriver();
driver.get("http://48.98.121.241:9000/iLamp/index.jsp");
driver.findElement(By.name("username")).clear();
driver.findElement(By.name("username")).sendKeys("00000000");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("12345");
driver.findElement(By.id("login-btn")).click(); //获取cookie信息
cookies = driver.manage().getCookies();
driver.close();
}
再次访问网页,需要携带之前获得的cookie,site自带addCookies方法,但我用此方法添加的cookie并不能通过验证
for (Cookie cookie : cookies) {
site.addCookie(cookie.getName().toString(),cookie.getValue().toString());
}
通过postman请求发现,在请求头里,新建Cookie,然后添加登陆获得的cookie信息,可以通过验证,由于我的cookie内容只有jession和lamp-nari-shiro有效,故Cookie里只添加了这两个信息。代码如下
for (Cookie cookie : cookies) {
if(cookie.getName().equals("JSESSIONID")) {
Cookie +=cookie.getName()+"="+cookie.getValue().toString()+";";
}
if(cookie.getName().equals("ilamp-nari-shiro")) {
Cookie +=cookie.getName()+"="+cookie.getValue().toString()+";";
}
}
至此,登录过程与cookie验证已经完成。
4. 数据结构化存储
4.1 建立带提取数据类
public class WeatherDao {
private String riseTime;
private String downTime;
private String city;
}
4.2 progress中把关键字段putFiled
if(page.getUrl().get().equals("http://48.91.121.241:9000/iLamp/mobile/device/weatherHefeng?cityNum=CN101190104")) {
String downTime = new JsonPathSelector("$.downTime").select(page.getRawText());
String city = new JsonPathSelector("$.city").select(page.getRawText());
String riseTime = new JsonPathSelector("$.riseTime").select(page.getRawText());
page.putField("downTime",downTime );
page.putField("city",city );
page.putField("riseTime", riseTime);
4.3 Spider启动时添加pipeLine,pipeLine中完成处理逻辑
启动时加入pipeline
Spider.create(miai).addPipeline(new WeatherPipeline()) .addUrl("https://www.oschina.net/").thread(1) .run();
pipeline处理逻辑
public class WeatherPipeline implements Pipeline{
public WeatherPipeline() {
// TODO Auto-generated constructor stub
}
@Override
public void process(ResultItems resultItems, Task task) {
// TODO Auto-generated method stub
String city="";
String riseTime="";
String downTime="";
for(Entry enty:resultItems.getAll().entrySet()) {
if(enty.getKey()!=null&&((String)enty.getKey()).equals("city")) {
city = (String)enty.getValue();
}
if(enty.getKey()!=null&&((String)enty.getKey()).equals("riseTime")) {
riseTime = (String)enty.getValue();
}
if(enty.getKey()!=null&&((String)enty.getKey()).equals("downTime")) {
downTime = (String)enty.getValue();
}
WeatherDao weather =new WeatherDao();
weather.setCity(city);
weather.setDownTime(downTime);
weather.setRiseTime(riseTime);
//后续持久化逻辑,存数据库或者文件或redis等内存数据库
}
}
}
欢迎相互讨论,交流学习。

本文详述WebMagic框架处理多种URL形式,包括绝对链接、相对链接及动态JS/Ajax请求,介绍如何实现系统登录与Cookie获取,以及数据结构化存储方法,适合爬虫开发者参考。

2064

被折叠的 条评论
为什么被折叠?



