学校实训作业:Java爬虫(WebMagic框架)的简单操作
项目名称:java爬虫
项目技术选型:Java、Maven、Mysql、WebMagic、Jsp、Servlet
项目实施方式:以认知java爬虫框架WebMagic开发为主,用所学java知识完成指定网站的数据爬取解析,并使用Servlet和Jsp展示到页面
实训环境:一人一机,边讲边练
实训简介:
本次实训的主要目的是增强学生对于WebMagic框架和Servlet的了解,并结合所学的理论知识进行爬虫实战。需要同学掌握包括目前市场上使用广泛的Mysql数据、Java语言、WebMagic框架和Servlet的开发,并了解大中型大数据行业的基本模式知识。
此次实训选择的案例有:
Mysql数据库基本操作
Java基本语法使用
WebMagic框架搭建并开发爬虫项目
通过学习这些内容可大大提升学生对计算机知识的理解,促进专业课程的学习,从而潜移默化的提升学生的就业竞争力。
步骤:
1、下载、安装好Maven,并在Eclipse中配置好Maven的相关设置。
1)、下载、安装Maven
下载地址:http://maven.apache.org/download.cgi,根据自己系统选择合适版本进行下载:

解压下载的文件到合适的位置即完成了Maven的安装:

2)、设置环境变量
复制Maven的安装路径下bin目录的路径,将其添加到电脑的环境变量中去:
复制bin目录所在的路径:

添加环境变量:

在cmd下输入:mvn --version 检查Maven是否安装成功,出现以下提示则安装成功:

3)、可忽略:修改Maven安装目录 conf下的settings.xml文件(E:\apache-maven-3.5.4\conf\settings.xml),来配置本地仓库的位置和将远程仓库镜像修改成阿里云镜像:
配置本地仓库,在<!-- localRepository........-->下面加上自己所要创建的本地仓库的地址(根据自身情况设置):

Maven仓库默认在国外,使用难免很慢,尤其是下载依赖的时候,速度贼慢,换成国内阿里云镜像后会在速度上有很大的提升:
<mirror>
<id>aliyun</id>
<name>aliyun Maven</name>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/repositories/central</url>
</mirror>

4)、Eclipse的配置
以下步骤,在每个人的电脑上显示的内容可能会不一样(截图来自不同的项目,请忽略包名、类名等信息,部分截图来自网络,不同截图里的相关信息可能不同),但操作步骤是一样的,只要照着做就行了,在Eclipse上安装maven,打开Eclipse点击window>prferences之后会弹出:


点击确定之后会出现:

点击finish之后:

在Eclipse中配置Maven:
打开Eclipse的首选项设置

找到Maven的配置项目

设置Maven的全局配置文件settings.xml

更新配置信息

2、在Eclipse中创建Maven项目
1)、开启eclipse,右键new——》other,如下图找到maven project或者直接搜索maven projec:
创建项目:

2)、选择Maven Project,请选中Create a simple project(skip archetype selection),之后点击Next :

3)、填写Group id和Artifact id, Version默认,Packaging默认为jar,Name,Description选填,其他的可以都不填写:

之后点击Finish即可,此时需要等待一段时间下载所需要的文件,创建后的完整项目结构应如下图所示:

3、编写Java爬虫项目代码,抓取https://hr.tencent.com/position.php网站的相关信息:
1)、所需要抓取网页内容:职位名称、职位类别、人数、地点、发布时间

2)、根据所要抓取的内容(抓取内容包括:职位名称、职位类别、人数、地点、发布时间),可参照下面的SQL语句设计数据库(mysql):
/*
SQLyog Ultimate v12.5.0 (64 bit)
MySQL - 5.5.27 : Database - mysql_java
*********************************************************************
*/ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`mysql_java` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `mysql_java`; /*Table structure for table `tencent_position` */ DROP TABLE IF EXISTS `tencent_position`; CREATE TABLE `tencent_position` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`p_name` varchar(200) NOT NULL,
`p_link` varchar(200) NOT NULL,
`p_type` varchar(100) NOT NULL,
`p_num` varchar(20) NOT NULL,
`p_location` varchar(20) NOT NULL,
`p_publish_time` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1125 DEFAULT CHARSET=utf8;
3)、在创建的项目下,首先需要配置好pom.xml,然后分别创建四个类和一个接口(名字自己取):MySQLUtils、TencentPageProcessor、TencentPosition、TencentPositionDao(接口)、TencentPositionDaoImpl

配置pom.xml:
pom.xml文件的设置:填写好<dependency..../dependency>后的内容后,一定记得要按Ctrl+S/保存按钮,之后Eclipse会自动从设置好的Maven仓库中下载所需要的文件,可能需要一定的时间:

dependency数据来自:http://mvnrepository.com/ 分别搜索:webmagic、mysql会显示相关内容

点击搜索得到的内容,复制框内的代码到pom.xml的<dependency..../dependency>代码块中:
可以在Maven Dependencies库中查看是否下载完成:

以下是示例代码,自己编码时,请记得一定要改动代码。
MySQLUtils类代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class MySQLUtils { private static Connection connection; public static Connection getConnection() throws ClassNotFoundException, SQLException {
if (connection == null) {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mysql_java";//URL、User、Password需根据自己的实际情况填写
String user = "root";
String password = "root";
return DriverManager.getConnection(url, user, password);
}
return connection;
} }
TencentPosition代码如下:
public class TencentPosition {
private String positionName;
private String positionLink;
private String positionType;
private String positionNum;
private String workLocation;
private String publishTime;
public TencentPosition() {
super();
}
public TencentPosition(String positionName, String positionLink, String positionType, String positionNum,
String workLocation, String publishTime) {
super();
this.positionName = positionName;
this.positionLink = positionLink;
this.positionType = positionType;
this.positionNum = positionNum;
this.workLocation = workLocation;
this.publishTime = publishTime;
}
public String getPositionName() {
return positionName;
}
public void setPositionName(String positionName) {
this.positionName = positionName;
}
public String getPositionLink() {
return positionLink;
}
public void setPositionLink(String positionLink) {
this.positionLink = positionLink;
}
public String getPositionType() {
return positionType;
}
public void setPositionType(String positionType) {
this.positionType = positionType;
}
public String getPositionNum() {
return positionNum;
}
public void setPositionNum(String positionNum) {
this.positionNum = positionNum;
}
public String getWorkLocation() {
return workLocation;
}
public void setWorkLocation(String workLocation) {
this.workLocation = workLocation;
}
public String getPublishTime() {
return publishTime;
}
public void setPublishTime(String publishTime) {
this.publishTime = publishTime;
}
@Override
public String toString() {
return "TencentPosition [positionName=" + positionName + ", positionLink=" + positionLink + ", positionType="
+ positionType + ", positionNum=" + positionNum + ", workLocation=" + workLocation + ", publishTime="
+ publishTime + "]";
}
}
TencentPositionDao接口代码如下:
public interface TencentPositionDao {
int add(TencentPosition position);
}
TencentPositionDaoImpl类代码如下:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class TencentPositionDaoImpl implements TencentPositionDao { public int add(TencentPosition position) {
String sql = "INSERT INTO tencent_position(p_name, p_link, p_type, p_num, p_location, p_publish_time)"
+ " VALUES(?, ?, ?, ?, ?, ?)";
Connection conn = null;
PreparedStatement pst = null;
try {
conn = MySQLUtils.getConnection();
pst = conn.prepareStatement(sql);
pst.setString(1, position.getPositionName());
pst.setString(2, position.getPositionLink());
pst.setString(3, position.getPositionType());
pst.setString(4, position.getPositionNum());
pst.setString(5, position.getWorkLocation());
pst.setString(6, position.getPublishTime());
return pst.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
pst = null;
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
conn = null;
}
}
}
return 0;
} }
TencentPageProcessor类代码如下:
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.JsonFilePipeline;
import us.codecraft.webmagic.processor.PageProcessor; public class TencentPageProcessor implements PageProcessor { private Site site = Site.me().setRetryTimes(5).setSleepTime(1000); private static TencentPositionDao dao = new TencentPositionDaoImpl(); public static AtomicLong count = new AtomicLong();
public static AtomicLong total = new AtomicLong(); public Site getSite() {
return site;
} public void process(Page page) {
List<String> urlList = page.getHtml().links().regex("https://hr.tencent.com/position.php\\?&start=\\d+").all();
System.out.println(urlList);
page.addTargetRequests(urlList); List<String> positionNames = page.getHtml().xpath("//tr[@class='odd']/td[1]/a/text()").all();
List<String> positionLinks = page.getHtml().xpath("//tr[@class='odd']/td[1]/a/@href").all();
List<String> positionTypes = page.getHtml().xpath("//tr[@class='odd']/td[2]/text()").all();
List<String> positionNums = page.getHtml().xpath("//tr[@class='odd']/td[3]/text()").all();
List<String> workLocations = page.getHtml().xpath("//tr[@class='odd']/td[4]/text()").all();
List<String> publishTimes = page.getHtml().xpath("//tr[@class='odd']/td[5]/text()").all();
for (int i = 0; i < positionNames.size(); i++) {
TencentPosition position = new TencentPosition();
position.setPositionName(positionNames.get(i));
position.setPositionLink(positionLinks.get(i));
position.setPositionType(positionTypes.get(i));
position.setPositionNum(positionNums.get(i));
position.setPublishTime(publishTimes.get(i));
position.setWorkLocation(workLocations.get(i));
dao.add(position);
} //String positionName = page.getHtml().xpath("//tr[@class='odd']/td[1]/a/text()").get();
//String positionType = page.getHtml().xpath("//tr[@class='odd']/td[2]/text()").get();
//String positionLink = "https://hr.tencent.com/" + page.getHtml().xpath("//tr[@class='odd']/td[1]/a/@href").get();
//String positionNum = page.getHtml().xpath("//tr[@class='odd']/td[3]/text()").get();
//String workLocation = page.getHtml().xpath("//tr[@class='odd']/td[4]/text()").get();
//String publishTime = page.getHtml().xpath("//tr[@class='odd']/td[5]/text()").get();
//page.putField("positionName", positionName);
//page.putField("positionLink", positionLink);
//page.putField("positionType", positionType);
//page.putField("positionNum", positionNum);
//page.putField("workLocation", workLocation);
//page.putField("publishTime", publishTime);
//TencentPosition position = new TencentPosition();
//position.setPositionName(positionName);
//position.setPositionLink(positionLink);
//position.setPositionType(positionType);
//position.setPositionNum(positionNum);
//position.setPublishTime(publishTime);
//position.setWorkLocation(workLocation);
//dao.add(position);
} public static void main(String[] args) {
Spider.create(new TencentPageProcessor())
.addUrl("https://hr.tencent.com/position.php?&start=0")
.addPipeline(new JsonFilePipeline("web_code"))
.thread(100)
.run();
} }
4、编码完成,点击运行、进行测试
当控制台显示如下内容时,则表示抓取成功:

此时可以查看自己的数据库看是否有数据,如果有数据,并且数据库中的数据和网页中需要抓取的数据一致,则表示Java爬虫项目已完成:

实验完成。
注意:实验完成后,请将源代码压缩为:名字.rar,并在这周五之前发送到我的邮箱:google.app@qq.com
转载请保留或注明出处:https://www.cnblogs.com/alibaba-inc/p/9242160.html
学校实训作业:Java爬虫(WebMagic框架)的简单操作的更多相关文章
- Java企业实训 - 01 - Java前奏
前言: 虽然个人专攻.NET方向,不过由于个人是干教育行业的,方方面面的东西,不能说都必须精通,但肯定多少都会涉及到. 一个菜鸟学员,从啥都不会,经过一步步学习,最后到企业上手掌管一个模块甚至一个项目 ...
- Java实训作业
1.编写程序:声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果. public class hello{ public static void main(String[ ...
- Java第一次实训作业
1.编写程序: 声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果. import java.util.Scanner; public class Hellowore { ...
- JAVA第三次实训作业
---恢复内容开始--- 1. 编写“学生”类及其测试类. “学生”类: 类名:Student 属性:姓名.性别.年龄.学号.5门课程的成绩 方法1:在控制台输出各个属性的值. 方法2:计算平均成绩 ...
- JAVA第二次实训作业
1.一维数组的创建和遍历. 声明并创建存放4个人考试成绩的一维数组,并使用for循环遍历数组并打印分数. 要求: 首先按“顺序”遍历,即打印顺序为:从第一个人到第四个人: 然后按“逆序”遍历,即打印顺 ...
- Java第一、二次实训作业
1.有1.2.3.4共4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去掉不满足条件的排列. 代码 pack ...
- 第一二次java实训作业
1. 声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果. package java1; public class java1 { static int a=5; pub ...
- Java第四次实训作业
1.编写“电费管理类”及其测试类. 第一步 编写“电费管理”类1)私有属性:上月电表读数.本月电表读数2)构造方法:无参.2个参数3)成员方法:getXXX()方法.setXXX()方法4)成员方法 ...
- Java实训作业1
1.编写程序:声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果 2.编写程序:从键盘输入圆的半径,计算圆的面积并输出. 3.编写程序:实现一个数字加密器.运行时输入加密 ...
随机推荐
- The entity type XXX is not part of the model for the current context.
今天遇到了一个奇葩问题,虽然解决了,但还是一脸懵,先附赠一下别人的解决方案:https://www.cnblogs.com/zwjaaron/archive/2012/06/08/2541430.ht ...
- Flask 教程 第二十章:加点JavaScript魔法
本文翻译自The Flask Mega-Tutorial Part XX: Some JavaScript Magic 这是Flask Mega-Tutorial系列的第二十部分,我将添加一个功能,当 ...
- Flask 教程 第十八章:Heroku上的部署
本文翻译自The Flask Mega-Tutorial Part XVIII: Deployment on Heroku 这是Flask Mega-Tutorial系列的第十八部分,我将在其中部署M ...
- 【代码审计】seacms 前台Getshell分析
一.漏洞分析 漏洞触发点search.php 211-213行 跟进parseIf 函数 ./include/main.class.php 这里要注意 3118行的位置,可以看到未做任何处理的eval ...
- 概率DP hdu 3366 .
题意:一个人被困在一个城堡里,面前有n条路,他自己有m百万元,选择每一条路都有p概率通过,q概率遇到士兵,1-p-q概率道路不通:遇到士兵的话需要上交1百万,如果不够钱,则被杀死,问的是最优情况下多少 ...
- java读/写文件
读取文件参考:https://blog.csdn.net/weixin_42129373/article/details/82154471 写入文件参考:https://blog.csdn.net/B ...
- angular 页面中引入静态 PDF 文件
在web开发时我们有时会需要在线预览PDF内容,在线嵌入pdf文件 常用的几种PDF预览代码片段如下: 方法一: <object type="application/pdf" ...
- 【Vue常用指令】
目录 v-html v-text v-for v-if v-show v-bind v-on v-model 指令修饰符 计算与侦听属性 自定义属性 获取DOM元素 "@ *** Vue.j ...
- PHP基础学习笔记2
一.数组 1.1 数值数组 1)自动分配 ID 键 ) ); ?> 即二维数组: 100 100 96 20 60 59 40 110 100 上面创建的二维数组自动分配ID键:下面以指定键的方 ...
- chomp/undef/标量 --Perl 入门第二章
1.chomp 用途:去掉字符串 末尾的换行符 $text="a line of text \n" chomp($text) #去除行末的换行符 chomp() --本质上是一个 ...