爬虫任务二:爬取(用到htmlunit和jsoup)通过百度搜索引擎关键字搜取到的新闻标题和url,并保存在本地文件中(主体借鉴了网上的资料)

采用maven工程,免着到处找依赖jar包

<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.zhaowu</groupId>
    <artifactId>pachong01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/cn.edu.hfut.dmic.webcollector/WebCollector -->
        <dependency>
            <groupId>cn.edu.hfut.dmic.webcollector</groupId>
            <artifactId>WebCollector</artifactId>
            <version>2.71</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
        <dependency>
            <groupId>net.sourceforge.htmlunit</groupId>
            <artifactId>htmlunit</artifactId>
            <version>2.29</version>
        </dependency>

    </dependencies>
</project>

直接上代码RenWu.class:

package com.zhaowu.renwu2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class RenWu {
    // 搜索页数
    private static int N = 6;
    // 搜索关键词
    private static String keyWord = "爬虫";
    // 第一页搜索结果
    private static HtmlPage firstBaiduPage;
    // Baidu对应每个搜索结果的第一页第二页第三页等等其中包含“&pn=1”,“&pn=2”,“&pn=3”等等,
    // 提取该链接并处理可以获取到一个模板,用于定位某页搜索结果
    private static String template = "";

    public static void main(String[] args) {
        goSearch(N, keyWord);
    }

    private static void goSearch(final int n, final String keyWord) {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                // 页数
                int x = n;
                System.out.println("爬取百度关于关键字“" + keyWord + "”搜索结果的前" + x + "页");
                FileUtil.toFile("爬取百度关于关键字“" + keyWord + "”搜索结果的前" + x + "页\n");

                //1.获取并输出第一页百度查询内容
                Elements firstElementsLink = null;
                try {
                    firstElementsLink = getFirstPage(keyWord);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                for (Element link : firstElementsLink) {
                    // 链接url
                    String linkHref = link.attr("href");
                    // 链接标题
                    String linkText = link.text();
                    if(linkHref.length() > 13 & linkText.length() > 4) {
                        String content = "链接url: " + linkHref + "\n\t链接标题: " + linkText + "\n";
                        System.out.println(content);
                        FileUtil.toFile(content);
                    }
                }

                //2.读取第二页及之后页面预处理
                // 以firstBaiduPage作为参数,定义template,即网页格式。
                nextHref(firstBaiduPage);

                //3.获取百度第一页之后的搜索结果
                for(int i = 1; i< x; i++) {
                    System.out.println("\n---------百度搜索关键字“" + keyWord + "”第" + (i + 1) + "页结果------");
                    FileUtil.toFile("\n---------百度搜索关键字“" + keyWord + "”第" + (i + 1) + "页结果------" + "\n");
                    // 根据已知格式修改生成新的一页的链接
                    String tempURL = template.replaceAll("&pn=1", "&pn=" + i + "");
                    // 显示该搜索模板
                    System.out.println("\t该页地址为:" + tempURL);
                    RenWu renWu = new RenWu();
                    // 实现摘取网页源码
                    String htmls = renWu.getPageSource(tempURL, "utf-8");
                    // 网页信息转换为jsoup可识别的doc模式
                    Document doc = Jsoup.parse(htmls);
                    // 摘取该页搜索链接
                    Elements links = doc.select("a[data-click]");
                    // 该处同上getFirstPage的相关实现
                    for (Element link : links) {
                        // 链接url
                        String linkHref = link.attr("href");
                        // 链接标题
                        String linkText = link.text();
                        if(linkHref.length() > 13 & linkText.length() > 4) {
                            String content = "链接url: " + linkHref + "\n\t链接标题: " + linkText + "\n";
                            System.out.println(content);
                            FileUtil.toFile(content);
                        }
                    }
                }
            }
        });
        thread.start();
    }

    public String getPageSource(String pageURL, String encoding) {
        // 输入:url链接&编码格式
        // 输出:该网页内容
        StringBuffer sb = new StringBuffer();
        try {
            // 构建一URL对象
            URL url = new URL(pageURL);
            // 使用openStream得到一输入流并由此构造一个BufferedReader对象
            InputStream in = url.openStream();
            InputStreamReader ir = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(ir);
            String line;
            while((line = br.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /*
     * 获取百度搜索第一页内容
     */
    public static Elements getFirstPage(String keyWord) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        //设置浏览器的User-Agent
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52);
        // HtmlUnit对JavaScript的支持不好,关闭之
        webClient.getOptions().setJavaScriptEnabled(false);
        // HtmlUnit对CSS的支持不好,关闭之
        webClient.getOptions().setCssEnabled(false);
        // 百度搜索首页页面
        HtmlPage htmlPage = webClient.getPage("http://www.baidu.com/");
        // 获取搜索输入框并提交搜索内容(查看源码获取元素名称)
        HtmlInput input = htmlPage.getHtmlElementById("kw");
        // 将搜索词模拟填进百度输入框(元素ID如上)
        input.setValueAttribute(keyWord);
        // 获取搜索按钮并点击
        HtmlInput btn = htmlPage.getHtmlElementById("su");
        // 模拟搜索按钮事件,获取第一页的html内容
        firstBaiduPage = btn.click();
        // 将获取到的百度搜索的第一页信息输出
        // 通过page.asXml()来获取百度首页的源代码,
        // 通过page.asTest()来获取页面的文字
        String content = firstBaiduPage.asXml().toString();
        // 转换为Jsoup识别的doc格式
        Document doc = Jsoup.parse(content);
        System.out.println("---------百度搜索关键字“" + keyWord + "”第1页结果--------");
        FileUtil.toFile("---------百度搜索关键字“" + keyWord + "”第1页结果--------" + "\n");
        // 返回包含类似<a......data-click=" "......>等的元素
        Elements firstElementsLink = doc.select("a[data-click]");
        // 返回此类链接,即第一页的百度搜素链接
        return firstElementsLink;
    }

    /*
     * 获取下一页地址
     */
    public static void nextHref(HtmlPage firstBaiduPage) {

        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52);
        webClient.getOptions().setJavaScriptEnabled(false);
        webClient.getOptions().setCssEnabled(false);
        // 获取到百度第一页搜索的底端的页码的html代码
        String morelinks = firstBaiduPage.getElementById("page").asXml();
        // 转换为Jsoup识别的doc格式
        Document doc = Jsoup.parse(morelinks);
        // 提取这个html中的包含<a href=""....>的部分
        Elements links = doc.select("a[href]");
        // 设置只取一次每页链接的模板格式
        boolean getTemplate = true;
        for (Element e : links) {
            // 将提取出来的<a>标签中的链接取出
            String linkHref = e.attr("href");
            if(getTemplate) {
                // 补全模板格式
                template = "http://www.baidu.com" + linkHref;
                getTemplate = false;
            }
        }
    }
}

导出到本地文件(末尾追加)的封装方发类FileUtil.class:

package com.zhaowu.renwu2;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileUtil {
    public static void toFile (String content) {
        File file = null;
        FileWriter fw = null;
        file = new File("/home/acer/桌面/aaa");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            fw = new FileWriter(file,true);
            fw.write(content);//向文件中复制内容
            fw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fw != null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

原文地址:https://www.cnblogs.com/sutao/p/9012361.html

时间: 2024-11-20 23:31:26

爬虫任务二:爬取(用到htmlunit和jsoup)通过百度搜索引擎关键字搜取到的新闻标题和url,并保存在本地文件中(主体借鉴了网上的资料)的相关文章

[Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

一. 文章介绍 前一篇文章"[python爬虫] Selenium爬取新浪微博内容及用户信息"简单讲述了如何爬取新浪微博手机端用户信息和微博信息. 用户信息:包括用户ID.用户名.微博数.粉丝数.关注数等. 微博信息:包括转发或原创.点赞数.转发数.评论数.发布时间.微博内容等. 它主要通过从文本txt中读取用户id,通过"URL+用户ID" 访问个人网站,如柳岩: http://weibo.cn/guangxianliuya 因为手机端数据相对精简简单,所以采用输

用JAVA制作一个爬取商品信息的爬虫(爬取大众点评)

很多企业要求利用爬虫去爬取商品信息,一般的开发模型如下: for i=1;i<=最大页号;i++ 列表页面url=商品列表页面url+?page=i(页号) 列表页面=爬取(列表页面url) 商品链接列表=抽取商品链接(列表页面)  for 链接 in 商品链接列表: 商品页面=爬取(链接) 抽取(商品页面); 这样的模型看似简单,但是有一下几个问题: 1)爬虫没有线程池支持. 2)没有断点机制. 3)没有爬取状态存储,爬取商品网站经常会出现服务器拒绝链接(反问次数过多),导致一旦出现 拒绝链接

第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号

第三百三十节,web爬虫讲解2-urllib库爬虫-实战爬取搜狗微信公众号 封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import json import random import re import urllib.error def hq_html(hq_url): """ hq_html()封装的爬虫函数,自动启用了用户代理和ip

scrapy-redis实现爬虫分布式爬取分析与实现

一 scrapy-redis实现分布式爬取分析 所谓的scrapy-redis实际上就是scrapy+redis其中对redis的操作采用redis-py客户端.这里的redis的作用以及在scrapy-redis的方向我在自己fork的repository(链接:)已经做了翻译(README.rst). 在前面一篇文章中我已经借助两篇相关文章分析了使用redis实现爬虫分布式的中心.归结起来就是:所有爬虫获取到的url(request)都放到一个redis queue中,并且所有爬虫都从单个r

第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息

第三百三十四节,web爬虫讲解2-Scrapy框架爬虫-Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻标题和rul地址 有多网站,当你浏览器访问时看到的信息,在html源文件里却找不到,由得信息还是滚动条滚动到对应的位置后才显示信息,那么这种一般都是 js 的 Ajax 动态请求生成的信息 我们以百度新闻为列: 1.分析网站 首先我们浏览器打开百度新闻,在网页中间部分找一条新闻信息 然后查看源码,看看在源码里是否有

使用htmlparse爬虫技术爬取电影网页的全部下载链接

昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚然,我们的重点在于如何灵活运用我们已学的技术,这就需要我们不断的练习,不停的思索和深入发掘,在了解了精髓和意义之后运用到实践中才是技术的最高境界. 今天呢,本着昨天的兴趣,想来爬一爬电影资源,中途为了找一个好用趁手的工具,也是费了不少心思,早上半天基本上都在学习和找资料的过程中度过,下午开始才进入状

[Python爬虫] Selenium爬取新浪微博移动端热点话题及评论 (下)

这篇文章主要讲述了使用python+selenium爬取新浪微博的热点话题和评论信息.其中使用该爬虫的缺点是效率极低,傻瓜式的爬虫,不能并行执行等,但是它的优点是采用分析DOM树结构分析网页源码并进行信息爬取,同时它可以通过浏览器进行爬取中间过程的演示及验证码的输入.这篇文章对爬虫的详细过程就不再论述了,主要是提供可运行的代码和运行截图即可.希望文章对你有所帮助吧~ 参考文章 [python爬虫] Selenium爬取新浪微博内容及用户信息 [Python爬虫] Selenium爬取新浪微博客户

第一个nodejs爬虫:爬取豆瓣电影图片

第一个nodejs爬虫:爬取豆瓣电影图片存入本地: 首先在命令行下 npm install request cheerio express -save; 代码: var http = require('https'); //使用https模块 var fs = require('fs');//文件读写 var cheerio = require('cheerio');//jquery写法获取所得页面dom元素 var request = require('request');//发送reques

Python爬虫入门 | 爬取豆瓣电影信息

这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬虫的大门啦~好啦,正式开始我们的第二节课<爬取豆瓣电影信息>吧!啦啦哩啦啦,都看黑板~1. 爬虫原理1.1 爬虫基本原理听了那么多的爬虫,到底什么是爬虫?爬虫又是如何工作的呢?我们先从"爬虫原理"说起.爬虫又称为网页蜘蛛,是一种程序或脚本.但重点在于:它能够按照一定的规则,自动