爬虫入门(实时新闻采集器)①
优采云 发布时间: 2020-08-10 19:13早在之前就想学一学爬虫并且仍然木有时间,这几天抽空学了写入门级的爬虫,接下来简单介绍下爬虫的具体步骤以及具体的类以及操作流程;(按照如下流程搭建爬虫项目)
按照五层开始搭建爬虫项目:
1.用户接口层
2.任务调度层
3.网络爬取层
4.数据解析层
5.数据持久化层
开始搭建项目
首先新建一个maven项目
把爬虫大约须要的类包打包好:
download包:负责下载url界面以及编码获取编码类的一些工具类
paser包:
persistence包:
persistence包:
pojos包:存放bean类的包
schedule包:负责接收外部传过来的url任务,通过一定的分发策略,将相应的url任务分发到采集任务当中
ui包:负责爬虫系统对外开放的接口设计与实现
utils包:编写一些常用的工具类的包
以及在外部新建一个seeds.txt文件
配置好pom.xml文件:
4.0.0
com.tl.spider
SimpleYouthNewsSpider4Job002
0.0.1-SNAPSHOT
nexus-aliyun
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public/
SimpleYouthNewsSpider4Job002
maven-assembly-plugin
jar-with-dependencies
make-assembly
package
assembly
maven-compilder-plugin
2.3.2
1.7
1.7
UTF-8
1)在Util包上面编撰一个读取文件的类(并返回一个以换行分割的列表,拿取系统的*敏*感*词*) 读取seeds.txt上面的内容:
public static List getFileLineList(String filePath,String charset) throws IOException{
File fileObj = new File(filePath);
FileInputStream fis = new FileInputStream(fileObj);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
List lineList = new ArrayList();
String temp = null;
while ((temp = br.readLine()) != null) {
temp = temp.trim();
if(temp.length()>0) {
lineList.add(temp);
}
}
br.close();
return lineList;
}
2)在储存常量的类上面编撰一个util类编撰一类储存常量
public class StaticValue {
public final static String NEXT_LINE="\n";
public final static String ENCODING_DEFAULT="utf-8";
}
3)在download包上面编撰一个爬取网页的类传入url的编码(url,charset)输出网页内容:
(但是这样网页的编码是固定传入没有自由应变)
public static String getHtmlSourceBySocket(String url,String charset) throws Exception {
URL urlObj = new URL(url);
InputStream is = urlObj.openStream();
InputStreamReader isr = new InputStreamReader(is,charset);
BufferedReader br = new BufferedReader(isr);
StringBuilder stringBuilder = new StringBuilder();
String temp = null;
int lineCounter = 0;
while((temp=br.readLine())!=null) {
if(lineCounter>0) {
stringBuilder.append(StaticValue.NEXT_LINE);
}
lineCounter++;
stringBuilder.append(temp);
}
br.close();
return stringBuilder.toString();
}
4)根据具体情况来改变爬虫所对应的编码方式,分为两种
第一种:根据网页源码上面的Conten-Type属性来获取编码( 最准的形式):
代码实现获取:
public static String getCharset(String url) throws Exception {
String finalCharset = null;
URL urlObj = new URL(url);
URLConnection urlConn = urlObj.openConnection();
//用header来获取url的charset
Map allHeaderMap = urlConn.getHeaderFields();
List kvList = allHeaderMap.get("Conten-Type");
if(kvList!=null&&!kvList.isEmpty()) {
String line = kvList.get(0);
String[] kvArray = line.split(";");
for (String kv : kvArray) {
String[] eleArray = kv.split("=");
if(eleArray.length==2) {
if(eleArray[0].equals("charset")) {
finalCharset = eleArray[1].trim();
}
}
}
}
System.out.println(finalCharset);//finalCharset为取出的Conten-Type的值
}
第二种:根据网页源码的…里面的meta上面对应的charset属性的值来获取编码
代码实现获取:
public static String getCharset(String url) throws Exception {
BufferedReader br = WebPageDownLoadUtil.getBR(url,StaticValue.ENCODING_DEFAULT);
String temp = null;
while((temp=br.readLine())!=null) {
temp = temp.toLowerCase();//把网页源码都转成小写
String charset = getCharsetVaue4Line(temp);
if(charset!=null) {
finalCharset=charset;
System.out.println(charset);
break;
}
if(temp.contains("")) {
break;
}
}
br.close();
}
根据第二种方式要搭建对应的正值表达式来匹配对应的网页依照网页的具体情况来设定,如:
public static String getCharsetVaue4Line(String line) {
String regex = "charset=\"?(.+?)\"?\\s?/?>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
String charsetValue = null;
if(matcher.find()) {
charsetValue = matcher.group(1);
}
return charsetValue ;
}
然后把前面两种情况结合一下,在第一种情况获取不到的情况下依据第二种方案来获取 :
结合代码为: