爬虫测试类,目的是爬取搜狐新闻到我们的本地(要求:新闻的标题作为文件的名称,新闻的内容作为文件的内容,以"标题.txt"的形式保存在本地)
(jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据)
步骤:
1.利用jsoup来模拟浏览器向一个网站发送一个请求,请求分为post和get请求
Connection connect = Jsoup.connect("http://news.sohu.com/");
2.指定请求的发送方式
Document document(通过请求返回过来的数据(html里的内容)) = connect.get();
3.向操作jq的方式那样来操作html的页面
Elements list16 = document.select(".list16");(因为文章的标题的div的class属性为list16所以获取class为list16的div)
4.获取div下的所有a标签
5.遍历所有a标签,获取title的属性值,拿到所有的title的值
6.获取a标签中的属性为href的值,这个就是文字内容的连接
7.拿到连接之后,就可以再次模拟浏览器发送请求
8.得到文章内容的相关页面,获取article标签
9.利用选择器获取文章内容
10.根据工具类保存到本地
11.解决反扒问题
for (Element div : list16) { //打印class为list16的div //System.out.println(div); //div下的所有a标签 Elements as = div.select("a"); for (Element a : as) { //System.out.println(a); //遍历所有a标签,获取title的属性值,拿到title的值 String title = a.attr("title"); title.replace("|", "").replace("\", "").replace("*", "").replace(":", "").replace(""", "").replace("?", "").replace("<", "").replace(">", ""); //System.out.println(title); //获取a标签中的属性为href的值,这个就是文字内容的连接 String url = a.attr("href"); if (!url.startsWith("http")) { url="http:"+url; } //这个判断是解决反扒问题 String text=null; if (!url.contains("subject")) { System.out.println(url); //拿到连接之后,就可以再次模拟浏览器发送请求 Connection connect2 = Jsoup.connect(url); Document document2 = connect2.get(); //得到文章内容的相关页面,获取article标签 Elements articleM = document2.select("article"); for (Element element : articleM) { //System.out.println(element); //如何获取标签内所有的内容? //利用选择器获取文章内容 text = element.text(); System.out.println(text); } } FileUtilIO.writeFile("G:\爬虫\articles\"+title, text, "utf-8"); } }
11.工具类
/** * @Title: writeFile * @Description: 按照指定的编码把内容写入指定的文件中 * @param path * @param content * @param charset * @throws IOException * @return: void */ public static void writeFile(String path, String content, String charset) throws IOException { // 创建写入的文件 File file = new File(path); // 判断父目录是否存在 if (!file.getParentFile().exists()) { // 创建父目录 file.getParentFile().mkdirs(); } // 创建输出流对象 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset));
if (content!=null) {
bw.write(content);
}
bw.flush(); bw.close(); } /** * @Title: readFile * @Description: 读取文件内容 * @param file * @param charset * @return * @throws IOException * @return: String */ public static String readFile(File file, String charset) throws IOException { // 创建输出流对象 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset)); // 定义缓冲对象 StringBuffer sb = new StringBuffer(); // 定义读取每行的结果 String content = null; // 循环读取 while ((content = br.readLine()) != null) { // 加入缓冲对象 sb.append(content); } // 关闭流 br.close(); // 返回结果 return sb.toString(); }
12.把爬取到的文件发送至卡夫卡
package com.bawei; import java.io.File; import java.io.IOException; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.alibaba.fastjson.JSON; import com.bawei.util.Cms_article; import com.bawei.util.FileUtilIO; //测试发送文章到kafka //需求1:读取爬虫爬取出来的文章,并且封装到一个article对象中,发送到kafka(作为一个生产者) //需求2:在cms系统中,编写一个消费者,然后接收爬虫项目发来的消息,并且成功的保存在cms_article表中 //这个类就是生产者的类 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:producer.xml") public class TestSendArticles2Kafka { @Autowired KafkaTemplate<String, String> kafkaTemplate; @Test public void testSendArticle2Kafka() throws IOException { //1.从G:爬虫articles下的所有文件 File file = new File("G:\爬虫\articles"); File[] listFiles = file.listFiles(); //2.遍历目录下的所有文件 for (File file2 : listFiles) { //System.out.println(file2.getName()); //3.拿到文件的名称,作为Article对象的title String flieName = file2.getName(); String title = flieName.replace(".txt",""); System.out.println(title); //4.拿到文件内容作为文章的content来封装 String content = FileUtilIO.readFile(file2, "utf8"); //System.out.println(content); //创建一个文章对象 Cms_article article = new Cms_article(); //4.1.把标题和内容封装到一个对象里 article.setTitle(title); article.setContent(content); //5.补全文章对象的其他属性 article.setChannel_id(2); article.setCategory_id(1); //6.把这个文章对象,转成json串(提高效率) //fastJson的方式把对象,转成json串 String jsonString = JSON.toJSONString(article); //7.发送至kafka //7.1.在爬虫项目中整合kafka的生产者 //7.2.导入kafka的依赖 //7.3.复制producer.xml配置文件,修改ip和主题名称 //7.4.加载这个配置文件,并注入kafkatemplate,然后就可以调用发送方法 kafkaTemplate.send("cms_articles",jsonString); } } }