Java开发笔记Ⅱ(Jsoup爬虫)
Jsoup 爬虫
Java 也能写爬虫!!!
Jsoup重要对象如下:
Document:文档对象,每个html页面都是一个Document对象
Element:元素对象,一个Document对象里有多个Element对象
Node:节点对象,用于存储数据,标签名称、属性都是节点对象
Jsoup的主要方法如下:
static Connection connect(String url) 创建URL连接
static Document parse(File in, String charsetName) 解析文件为 Document 对象
static Document parse(String html) 解析html代码为 Document 对象
(虽然上边是最主要的方法,但是下边这段代码中,是用 document对象 + css 选择器来获取的信息)
爬虫示例(豆瓣)
/*** 通过访问接口获取代理IP*/public void initIPPool() {System.out.println("开始获取IP...");Process proc;try {// 这个代码之前是python改的,这里偷懒直接调用,这个文件贴在后边proc = Runtime.getRuntime().exec("python getIP.py");BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));String line = null;while ((line = in.readLine()) != null) {System.out.println(line);}in.close();proc.waitFor();} catch (Exception e) {System.out.println(e.toString());}System.out.println("成功获取代理IP");}/*** 从存储代理IP的文件获取代理IP*/public void loadIPPool() {File file = new File("ipPool.txt");List<String> list = new ArrayList<String>();synchronized (this) {BufferedReader reader = null;try {reader = new BufferedReader(new FileReader(file));String tempString = null;// 一次读入一行,直到读入null为文件结束while ((tempString = reader.readLine()) != null) {list.add(tempString);}reader.close();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e1) {System.out.println(e1.toString());}}}}System.out.println(list);myIPPool = list.toArray(new String[list.size()]);System.out.println("成功载入IP代理池");}public String crawlOnce(Integer start) {StringBuilder finalResult = new StringBuilder();Random random = new Random();// 请求地址String url ="http://movie.douban.com/j/new_search_subjects?sort=T&range=0,10&tags=&start=" +(start);HttpGet request = new HttpGet(url);String proxyIp = myIPPool[random.nextInt(myIPPool.length)];while (proxyIp.split(":").length != 2) {// 在代理ip池里随机获取一个ipproxyIp = myIPPool[random.nextInt(myIPPool.length)];}HttpHost proxy = new HttpHost(proxyIp.split(":")[0],Integer.parseInt(proxyIp.split(":")[1]));SSLContextBuilder builder = new SSLContextBuilder();// 全部信任 不做身份鉴定PoolingHttpClientConnectionManager cm = null;SSLConnectionSocketFactory sslsf = null;try {builder.loadTrustMaterial(null, new TrustStrategy() {@Overridepublic boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {return true;}});sslsf = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello","SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);Registry<ConnectionSocketFactory> registry =RegistryBuilder.<ConnectionSocketFactory>create().register("http",new PlainConnectionSocketFactory()).register("https", sslsf).build();cm = new PoolingHttpClientConnectionManager(registry);cm.setMaxTotal(200);//max connection} catch (Exception e) {System.out.println(e.toString());return "";}//设置认证CredentialsProvider provider = new BasicCredentialsProvider();//第一个参数对应代理httpHost,第二个参数设置代理的用户名和密码,如果代理不需要用户名和密码,填空provider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("", ""));//实例化CloseableHttpClient对象CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).setConnectionManagerShared(true).setDefaultCredentialsProvider(provider).build();RequestConfig config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(CONNECTION_TIME_OUT).setConnectionRequestTimeout(CONNECTION_TIME_OUT).setSocketTimeout(CONNECTION_TIME_OUT).build();request.setConfig(config);//添加请求头request.addHeader("User-Agent", myUAPool[random.nextInt(myUAPool.length)]);request.addHeader("Cookie", myCookies[random.nextInt(myCookies.length)]);request.addHeader("Accept-Language", "zh-CN,zh;q=0.9");request.addHeader("Sec-Fetch-Mode", "cors");request.addHeader("Sec-Fetch-Site", "same-origin");HttpResponse response = null;BufferedReader rd = null;try {response = httpClient.execute(request);rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));} catch (IOException e) {logError(start);return "";}String line = "";StringBuilder result = new StringBuilder();while (true) {try {line = rd.readLine();if (line == null) {break;}} catch (IOException e) {logError(start);break;}// 请求返回了html页面if (line.equals("") || line.charAt(0) == '<') {break;}result.append(line);}System.out.println((start) + "--result:" + result);JSONObject res = JSONObject.parseObject(String.valueOf(result));if (res == null || !res.containsKey("data")) {logError(start);return "";}JSONArray jsonArray = res.getJSONArray("data");for (int i = 0; i < jsonArray.size(); i++) {JSONObject jo = jsonArray.getJSONObject(i);// 通过详情链接爬取电影详情finalResult.append(crawlDetails(jo.getString("url")));}return finalResult.toString();}// 爬取详情private String crawlDetails(String url) {String result = "";Random random = new Random();try {String proxyIp = myIPPool[random.nextInt(myIPPool.length)];// myUAPool这里可以换几个浏览器把useragent手写在变量里Connection con = Jsoup.connect(url).proxy(proxyIp.split(":")[0], Integer.parseInt(proxyIp.split(":")[1])).timeout(10000).userAgent(myUAPool[random.nextInt(myUAPool.length)]).header("Accept-Language", "zh-CN,zh;q=0.9").header("Cookie", myCookies[random.nextInt(myCookies.length)]).timeout(CONNECTION_TIME_OUT); // 设置连接超时时间// 执行连接,获取页面Connection.Response response = con.execute();Document document = con.get();String info = document.select("#info").text();// IDresult += url.substring(33, url.length() - 1);// 标题result += "," + document.select("#content > h1 > span:nth-child(1)").text();// 年份result += "," + document.select("#content > h1 > span.year").text();// 导演result += "," + document.select("#info > span:nth-child(1) > span.attrs > a").text();// 编剧result += "," + document.select("#info > span:nth-child(3) > span.attrs").text();// 主演result += "," + document.select("#info > span.actor > span.attrs").text();// 类型result += "," + document.select("[property=v:genre]").text();// 产地result += "," + info.substring(info.indexOf("制片国家/地区: "), info.indexOf(" 语言:")).substring("制片国家/地区: ".length());// 语言if (info.contains(" 上映日期:")) {result += "," + info.substring(info.indexOf("语言: "), info.indexOf(" 上映日期:")).substring("语言: ".length());} else {result += "," + info.substring(info.indexOf("语言: ")).substring("语言: ".length());}// 片长result += "," + document.select("[property=v:genre]").attr("content");// 评分result += "," +document.select("#interest_sectl > div > div.rating_self.clearfix > strong").text();// 5result += "," + document.select("#interest_sectl > div.rating_wrap.clearbox > div" +".ratings-on-weight > div:nth-child(1) > span" +".rating_per").text();// 4result += "," + document.select("#interest_sectl > div.rating_wrap.clearbox > div" +".ratings-on-weight > div:nth-child(2) > span" +".rating_per").text();// 3result += "," + document.select("#interest_sectl > div.rating_wrap.clearbox > div" +".ratings-on-weight > div:nth-child(3) > span" +".rating_per").text();// 2result += "," + document.select("#interest_sectl > div.rating_wrap.clearbox > div" +".ratings-on-weight > div:nth-child(4) > span" +".rating_per").text();// 1result += "," + document.select("#interest_sectl > div.rating_wrap.clearbox > div" +".ratings-on-weight > div:nth-child(5) > span" +".rating_per").text();// 评分人数result += "," + document.select("[property=v:votes]").text();// 评论数result +="," + document.select("#comments-section > div.mod-hd > h2 > span > a").text();System.out.println(proxyIp + " " + result);} catch (IOException e) {System.out.println(e.toString());}return result + "\n";}
获取代理IP的代码
# coding=UTF-8import requests
import jsonclass FreeIP():def __init__(self):# 代理ip网站self.url = "http://proxylist.fatezero.org/proxy.list"self.headers = {"User-Agent": "这里改为浏览器的useragent"}def check_ip(self, ip_list):correct_ip = []for ip in ip_list:if len(correct_ip) > 10: # 可以根据自己的需求进行更改或者注释掉breakip_port = "{}:{}".format(ip["host"], ip["port"])proxies = {'https': ip_port}try:# 如果请求该网址,返回的IP地址与代理IP一致,则认为代理成功response = requests.get('https://icanhazip.com/', proxies=proxies,timeout=3).text # 可以更改timeout时间if response.strip() == ip["host"]:# print("可用的IP地址为:{}".format(ip_port))correct_ip.append(ip_port)except:# print("不可用的IP地址为:{}".format(ip_port))return correct_ipdef run(self):response = requests.get(url=self.url).content.decode()ip_list = []proxies_list = response.split('\n')for proxy_str in proxies_list:try:proxy = {}proxy_json = json.loads(proxy_str)if proxy_json["anonymity"] == "high_anonymous" and proxy_json["type"] == "https":host = proxy_json['host']port = proxy_json['port']proxy["host"] = hostproxy["port"] = portip_list.append(proxy)except:correct_ip = self.check_ip(ip_list)file_path = 'ipPool.txt'# 写入这个文件with open(file_path, mode='w', encoding='utf-8') as file_obj:for i in correct_ip:file_obj.write(i + "\n")if __name__ == '__main__':ip = FreeIP()ip.run()
相关文章:
Java开发笔记Ⅱ(Jsoup爬虫)
Jsoup 爬虫 Java 也能写爬虫!!! Jsoup重要对象如下: Document:文档对象,每个html页面都是一个Document对象 Element:元素对象,一个Document对象里有多个Element对象 Node&#…...
一五三、MAC 安装MongoDB可视化工具连接
若没有安装brew包管理工具,在命令行输入安装命令 /bin/bash -c “$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)”上面步骤安装完成后,开始安装MongoDB,输入安装命令: brew tap mongodb/brewbrew u…...
ULTRAINTERACT 数据集与 EURUS 模型:推动开源大型语言模型在推理领域的新进展
在人工智能的浪潮中,大型语言模型(LLMs)已经成为推动自然语言处理技术发展的关键力量。它们在理解、生成语言以及执行复杂任务方面展现出了巨大的潜力。然而,尽管在特定领域内取得了显著进展,现有的开源LLMs在处理多样…...
【leetcode刷题】面试经典150题 , 27. 移除元素
leetcode刷题 面试经典150 27. 移除元素 难度:简单 文章目录 一、题目内容二、自己实现代码2.1 方法一:直接硬找2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 2.2 方法二:排序整体删除再补充2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 三、…...
红队内网攻防渗透:内网渗透之内网对抗:横向移动篇PTH哈希PTT票据PTK密匙Kerberoast攻击点TGTNTLM爆破
红队内网攻防渗透 1. 内网横向移动1.1 首要知识点1.2 PTH1.2.1 利用思路第1种:利用直接的Hash传递1.2.1.1、Mimikatz1.2.2 利用思路第2种:利用hash转成ptt传递1.2.3 利用思路第3种:利用hash进行暴力猜解明文1.2.4 利用思路第4种:修改注册表重启进行获取明文1.3 PTT1.3.1、漏…...
springBoot不同module之间互相依赖
在 Spring Boot 多模块项目中,不同模块之间的依赖通常是通过 Maven 或 Gradle 来管理的。以下是一个示例结构和如何设置这些依赖的示例。 项目结构 假设我们有一个多模块的 Spring Boot 项目,结构如下: my-springboot-project │ ├── p…...
[modern c++] 类型萃取 type_traits
前言: #include <type_traits> type_traits 又叫类型萃取,是一个在编译阶段用于进行 类型判断/类型变更 的库,在c11中引入。因为其工作阶段是在编译阶段,因此被大量应用在模板编程中,同时也可以结合 constexpr…...
函数模板和类模板的区别
函数模板和类模板在C中都是重要的泛型编程工具,但它们之间存在一些显著的区别。以下是它们之间的主要区别: 实例化方式: 函数模板:隐式实例化。当函数模板被调用时,编译器会根据传递给它的参数类型自动推断出模板参数…...
ChatGPT 提示词技巧一本速通
目录 一、基本术语 二、提示词设计的基本原则 三、书写技巧 2.1 赋予角色 2.2 使用分隔符 2.2 结构化输出 2.3 指定步骤 2.4 提供示例 2.5 指定长度 2.6 使用或引用参考文本 2.7 提示模型进行自我判断 2.8 思考问题的解决过程 编辑 2.10 询问是否有遗漏 2.11 …...
【windows解压】解压文件名乱码
windows解压,文件名乱码但内容正常。 我也不知道什么时候设置出的问题。。。换了解压工具也没用,后来是这样解决的。 目录 1.环境和工具 2.打开【控制面板】 3.点击【时钟和区域】 4.选择【区域】 5.【管理】中【更改系统区域设置】 6.选择并确定…...
使用Flink CDC实时监控MySQL数据库变更
在现代数据架构中,实时数据处理变得越来越重要。Flink CDC(Change Data Capture)是一种强大的工具,可以帮助我们实时捕获数据库的变更,并进行处理。本文将介绍如何使用Flink CDC从MySQL数据库中读取变更数据࿰…...
学生课程信息管理系统
摘 要 目前,随着科学经济的不断发展,高校规模不断扩大,所招收的学生人数越来越 多;所开设的课程也越来越多。随之而来的是高校需要管理更多的事务。对于日益增 长的学生相关专业的课程也在不断增多,高校对其管理具有一…...
如何看待鸿蒙HarmonyOS?
鸿蒙系统,自2019年8月9日诞生就一直处于舆论风口浪尖上的系统,从最开始的“套壳”OpenHarmony安卓的说法,到去年的不再兼容安卓的NEXT版本的技术预览版发布,对于鸿蒙到底是什么,以及鸿蒙的应用开发的讨论从来没停止过。…...
【论文复现|智能算法改进】一种基于多策略改进的鲸鱼算法
目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 SCI二区|鲸鱼优化算法(WOA)原理及实现【附完整Matlab代码】 2.改进点 混沌反向学习策略 将混沌映射和反向学习策略结合,形成混沌反向学习方法,通过该方 法…...
yarn安装配置及使用教程
Yarn 是一款 JavaScript 的包管理工具,是 Facebook, Google, Exponent 和 Tilde 开发的一款新的 JavaScript 包管理工具,它提供了确定性、依赖关系树扁平化等特性,并且与 npm 完全兼容。以下是 Yarn 的安装及使用教程: Yarn 安装…...
有那么点道理。
...
蔚蓝资源包和数据分析
代码如下 /* * COMPUTER GENERATED -- DO NOT EDIT* */#include <windows.h>static FARPROC __Init_Fun_2__; int __RestartAppIfNecessary__Fun() {return 0; } int Init_Fun() {__Init_Fun_2__();return 1; }static FARPROC __GameServer_BSecure__; static FARPROC _…...
MySQL----利用Mycat配置读写分离
首先确保主从复制是正常的,具体步骤在MySQL----配置主从复制。MySQL----配置主从复制 环境 master(CtenOS7):192.168.200.131 ----ifconfig查看->ens33->inetslave(win10):192.168.207.52 ----ipconfig查看->无线局域网适配器 WLA…...
【科学计算与可视化】2. pandas 基础
1. 安装 Pandas 首先,确保你已经安装了 Pandas。你可以使用以下命令安装:pip install pandas 2. 导入 Pandas 在开始使用 Pandas 之前,你需要先导入它:import pandas as pd 3. 创建数据结构 Pandas 主要有两种数据结构&#…...
医学记录 --- 腋下异味
逻辑图地址 症状 病因 汗液分泌旺盛:由于天气炎热、活动出汗、肥胖等因素导致汗液分泌旺盛,可引起腋下有异味表现。在这种情况下,建议保持身体清洁,特别是在炎热和潮湿的环境下。可以使用抗菌洗液、喷雾或霜剂来帮助减少细菌滋…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
