[ JavaCrawler ]利用Jsoup与 HttpCLient爬取豆瓣电影数据

1.解析页面


影片信息的地址栏链接

首先访问需要爬取的页面
在这里插入图片描述

https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=%E7%94%B5%E5%BD%B1,2019

在地址栏可以看到,当前网页的一些状态信息

sort=U (排序方式)
range=0,10 (评分筛选区间)
tags=%E7%94%B5%E5%BD%B1,2019 (最上方选择的标签)

我们划到网页底部,点击加载更多
在这里插入图片描述
发现网页内容变多了,但是URL并没有改变

https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=%E7%94%B5%E5%BD%B1,2019

这是因为豆瓣采用异步加载技术,每次访问只修改局部数据
异步加载
如果这里我们直接使用Jsoup解析
页面元素
Document doc = Jsoup.parse(new URL("http://www.baidu.com"), 10000);
Elements elements = doc.selct(div.list-wp)
是获取不到影片信息的


存储影片信息的实际链接

但是我们发现,在点击加载更多之后
检查元素的 Network 的XHR中多出了新的数据
Network
点击可以看到 Headers 中有一个 Response URL
Headers
我们访问该链接
Response URL
可以看到影片的信息数据以JSON格式展现出来
JSON
对比这两个链接会发现
比较
在原有链接的基础上
新加了 start( 影片信息开始位置 ) 和 year_range(选择的年份范围)

我们尝试更改实际链接(修改start,并将start放到最后,方便后续修改链接)访问其他的影片信息
start=60
发现是可行的
所以,我们采用 Response URL 加修改 start 的方式来获取我们的影片信息链接


2.需要爬取的信息

在 影片信息的实际链接 中我们可以获取到

directors : [“庵野秀明”,“鹤卷和哉”,“大塚雅彦”]
rate : 9.4
title : 新世纪福音战士剧场版:Air/真心为你
url : https://movie.douban.com/subject/1308892/
casts : [“绪方惠美”,“林原惠美”,“三石琴乃”,“宫村优子”,“山口由里子”]
cover : https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2250316512.webp
id : 1308892

但如果想进一步获取影片更详细的信息(比如:类型、制片国家、上映日期 )
就需要访问影片详情界面(就是实际链接中url的值)
详情页面
利用 Jsoup 对页面元素进行解析
页面元素1
页面元素2
知道了想要获取的信息之后,就可以在数据库中建表
MySQL


3.编写工具类

虽然 Jsoup 也可以用 URL 直接获取页面内容
在网页的抓取上,HttpClient 要优于 Jsoup(HttpClient可以设置代理、 设置连接超时等等功能)
所以我们使用 HttpClient 抓取网页内容,Jsoup 解析网页元素


HttpUtils

public class HttpUtils {
   

    private PoolingHttpClientConnectionManager cm;
    private ArrayList<String> agents;

    public HttpUtils() {
   
        // 创建连接池管理器
        this.cm = new PoolingHttpClientConnectionManager();
        // 设置连接数
        this.cm.setMaxTotal(100);
        // 设置每个主机(理解为网站,如:百度10个、网易10个)的最大连接数
        this.cm.setDefaultMaxPerRoute(10);

        //初始化 User-Agent 信息
        this.agents = new ArrayList<String>();
        // 添加 User-Agent 信息
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36");
        agents.add("Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36");
        agents.add("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11");
        agents.add("Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER");
        agents.add("Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0");
        agents.add("Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0");
        agents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36");
        System.out.println("<--------- HttpUtils initialization success --------->");
    }


    /**
     * 获取页面源代码
     *
     * @param url 网页链接
     * @return 页面源代码
     */
    public String doGetHtml(String url) {
   
        // 通过连接池获取 httpClient
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();

        HttpGet httpGet = new HttpGet(url);

        // 伪造 User-Agent(反反爬虫)
        int agentNum = new Random().nextInt(agents.size());// 生成一个范围在 0-x(不包含x)内的任意正整数
        httpGet.addHeader("User-Agent", agents.get(agentNum));

        // 设置请求信息
        httpGet.setConfig(getConfig());

        // 定义 response,方便 finally 中关闭
        CloseableHttpResponse response = null;
        try {
   
            response = httpClient.execute(httpGet);
            // 获取并判断,状态码是否正常(正常值:200)
            if (response.getStatusLine().getStatusCode() == 200) {
   
                // 判断响应体是否为空,不为空则获取内容
                if (response.getEntity() != null) {
   
                    // 获取响应体,并指定 UTF-8 编码
                    String content
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值