webmagic入门-爬取校内电影网信息

使用webmagic框架爬取学校内网的电影资源信息


写在前面

说到爬虫,估计很多人的第一反应就是Python的Scrapy框架,确实,Scrapy框架可能是当下最为流行的爬虫框架了,这一点从github上Star数量就可以看出,但是由于我自己对于Python并不太熟悉,所以没能够体验这个框架的魅力,所以这篇文章的主角是另一个用java编写爬虫框架WebMagic,WebMagic框架是由国人黄亿华先生开发。


关于架构

WebMagic的总体架构非常简单,主要由四个组件构成,分别是: Downloader、PageProcessor、Scheduler以及Pipeline,这四个组件对应了爬虫生命周期中的下载、处理、管理和持久化等功能。官方给出的结构图如下:

webmagic


入门程序

入门级的程序非常简单,只需要我们定制爬虫的核心借口PageProcessor的实现即可,当然中间可能需要了解一些关于xpath以及css选择器抽取链接的知识。这一部分,你也可以参考WebMagic中文文档

创建maven项目

使用IDEA来创建Maven项目,项目的创建过程很简单,所以过程就不截图了,最终的结构大致如下:

maven

配置依赖

依赖部分,由于是入门程序,所以仅配置了webmagic-core以及webmagic-extension两个必须的依赖,而maven-compiler-plugin是为了避免IDEA在刷新pom文件后language-level重置为jdk5的问题,IDEA默认的language-level为jdk5,如果不修改,会导致代码中的注解或者其他的一些特性无法识别,所以我这里将其修改为jdk8

level

完整的pom文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mackvord</groupId>
<artifactId>webmagic</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<!-- WebMagic核心依赖 -->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<!-- WebMagic扩展依赖 -->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
</dependencies>

<!-- 解决IDEA刷新pom文件后,Modules下language-level重置为JDK5的问题 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

配置日志

如果你使用官方的demo来实现一个简单的爬虫的时候,你会发现,会报一个错误:

1
2
3
4
Picked up _JAVA_OPTIONS:   -Dawt.useSystemAAFontSettings=gasp
log4j:WARN No appenders could be found for logger (us.codecraft.webmagic.scheduler.QueueScheduler).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

这是因为没有配置日志所导致的,所以需要把log4j.properties文件配置好,放到resources目录下

log4j

具体的配置如下

1
2
3
4
5
6
log4j.rootLogger=WARN, stdout
# log4j.rootLogger=WARN, stdout, logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

如果你使用官方提供的入门案例并且是使用maven来构建项目的话,可能会碰到javax.net.ssl.SSLException: Received fatal alert: protocol_version这个错误,具体的解决方案请参考https://segmentfault.com/a/1190000014202558


抽取链接和信息

这一部分就是通过分析页面的结构,提取我们需要的信息,通过观察发现,需要抽取的链接存在一定的规律,但是链接非常地长,如果用正则可能比较麻烦,所以这里我选择使用css选择器进行链接抽取

page

经过分析,直接使用以下代码就能获取所有分类的链接

1
List<String> links = page.getHtml().css("ul.mainleve2").links().all();

获取链接之后就是抽取我们需要的信息了,通过查看源代码发现,所有的电影或者视频都是使用以下的html代码包裹

1
<span class="programName">xxxx</span></a></li>

page

所以信息的抽取的代码如下:

1
2
3
4
// 抽取分类
page.putField(category, page.getHtml().xpath("//div[@class='programTop']/h1/text()").all());
// 抽取电影或者视频名称
page.putField(title, page.getHtml().xpath("//span[@class='programName']/text()").all());

定制process核心接口实现

PageProcessor是定制爬虫的核心接口,在process()方法中编写抽取的逻辑,具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
/**
* process是定制爬虫的核心接口,在process()方法中编写抽取的逻辑
*/
public void process(Page page) {
String index = "Title";
// 抽取链接
List<String> links = page.getHtml().css("ul.mainleve2").links().all();
// 将所有的链接添加到请求队列中
page.addTargetRequests(links);
page.putField(category, page.getHtml().xpath("//div[@class='programTop']/h1/text()").all());
page.putField(index, page.getHtml().xpath("//span[@class='programName']/text()").all());
if (page.getResultItems().get(index) == null) {
//skip this page
page.setSkip(true);
}
}

可以发现,相比于官方提供的demo,我仅仅只是修改的链接的抽取以及想要获取的信息,完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.mackvord.demo;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;

import java.util.List;

/**
* 使用WebMagic创建第一个Java爬虫
* @author: mackvord
* @create: 18-9-28
*/
public class FirstDemo implements PageProcessor {

/**
* 抓取网站的相关配置,包括编码、抓取时间、重试次数等
*/
private Site site = Site.me().setRetryTimes(3).setSleepTime(100);

@Override
/**
* process是定制爬虫的核心接口,在process()方法中编写抽取的逻辑
*/
public void process(Page page) {
String index = "Title";
String category = "category";
// 抽取链接
List<String> links = page.getHtml().css("ul.mainleve2").links().all();
// 将所有的链接添加到请求队列中
page.addTargetRequests(links);
page.putField(category, page.getHtml().xpath("//div[@class='programTop']/h1/text()").all());
page.putField(index, page.getHtml().xpath("//span[@class='programName']/text()").all());
if (page.getResultItems().get(index) == null) {
//skip this page
page.setSkip(true);
}
}

@Override
public Site getSite() {
return site;
}

public static void main(String[] args) {
String url = "http://navod.scse.com.cn/nn_cms/data/template/100000/200003/index_v3_001.php" +
"?nns_template_type=100000&nns_template_id=200003&nns_user_id=g%2C172.16.146.247%2C5badd4122096a7b" +
"&nns_tag=31&nns_media_asset_id=movies&nns_parent_category_id=&nns_category_id=1000023" +
"&nns_page_name=movie";
Spider.create(new FirstDemo()).thread(5).addUrl(url).run();
}
}

效果

result


结语

这仅仅是使用webmagic框架的入门级程序,还有相当多可以改进的地方,现在我们爬到的数据都是直接在控制台打印出来,并没有对数据进行进一步的处理,比如说将数据保存到数据库,数据分析等等,所以接下来就是研究怎么将数据保存到数据库、以及进行数据分析。


如果您觉得我的文章对您有帮助,请随意赞赏,您的支持将鼓励我继续创作!
0%