- Java 版本
- 思路:
- 预备工作:
- 简述
- 代码
- python版本
- 代码
这个实战文章仅作为自己学习笔记记录;使用java和python爬取相同的内容,由于爬取内容涉及个人信息,去除了敏感信息,作为学习记录!python实战那篇被官方禁了 苦笑
- 定位需要的信息;
- 处理信息;
- 写入表格;
-
导包
使用Maven创建项目;
导包的时候直接在pom.xml添加依赖即可完成导包;不需要下载到本地添加;
Jsoup 包依赖org.jsoup jsoup 1.9.2 jxl 包依赖
net.sourceforge.jexcelapi jxl 2.6.12 添加完刷新一下
也可以下载到本地(针对不是Maven项目)
jxl 包下载官网
- 使用python和java思路差不多相同,都是定位到关键信息;
java:提取到信息之后保存到表格的过程,第一思路是跟写python那一篇一样使用字典,但是查了一些资料,实现不了;
第二个想到的是一边查找一边写入,这个过程就要先创建出一个工作表,就需要导入jxl包,这个是表单创建需要的包; - python和java
在去除提取信息的问号:
java:str.resplaceAll(“[?]”,"");使用这个一直去不掉?,
如果使用python str.strip("?") 直接将问号去掉;
去除空格:
java: str.trim() //去除首尾空格
python : str.strip() # 默认去除空格
字符串子串:
java : str.substring(beg,end); //需要开头和尾部的位置
python :直接使用切片; - .csv 和 .xls的区别
| 区别 | .csv | .xls |
|---|---|---|
| 文件格式 | 文本 | 二进制文件 |
| 全称 | Comma Separated Values | 微软的电子文档Excel |
| 操作 | 只是一个文本文件,存储数据,不包括格式,公式,宏; | 存储数据,还能对数据进行操作 |
| 后缀 | .csv分隔文本文件 | 电子表格.xls或者.xlsx |
| 打开方式 | 可以使用记事本打开编辑 | 不能使用记事本打开,只能用打开表格的方式打开,可以连接外部数据源获取数据 |
| 使用 | CSV读取大文件不会像execl那么简单,生成csv比较容易 | Excel 用于数据仓库,解析excel的编程语言库相对更大,更慢,更复杂 |
| 安全 | csv 相对安全,清楚区分数值和文本,按照原样存储 | 数值和文本没有明确的区分 |
| 标志 | 只能编写一次列标题 | 必须为每一行中的每一列都有一个开始标志和结束标志 |
| 导入 | 导入更快 | 导入慢,消耗更多的内存 |
| 内容 | 文本 | 文本,图表等 |
import org.jsoup.Jsoup; //java 爬虫的包
import org.jsoup.nodes.document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import jxl.write.*;
import jxl.*; // 写入表格的包
import java.io.*;
public class spider {
public static void main(String[] args) throws IOException, WriteException {
int teacherNum = 1; //定义第 n 个老师
int Titlelen = 8;
String biaoti = "姓名,职称,系、研究所,研究领域,讲授课程,办公电话,电子邮箱,办公地点,个人主页"; // 定义表格的Title
WritableWorkbook book = Workbook.createWorkbook((new File("teacher_info.xls"))); // 创建新的表格
WritableSheet sheet = book.createSheet("No1",0); // 创建工作页
for(int l=0;l<=Titlelen;l++) // 循环将title写入第一行
{
String[] Title = biaoti.split(","); // 将上面定义的字符串按照逗号划分
Label label = new Label(l,0,Title[l]); // 循环写入
sheet.addCell(label);
}
try {
String url = ""; //爬取网址
document document = Jsoup.connect(url).get();
Elements titleElement = document.getElementsByClass("mclb");//获取类名
for(int i=0; i<4;i++) // 循环前三个表单 教授,副教授,讲师
{
for (int j = 0; j
由于之前这篇被官方认为是违规博文,所以之前的学习日记被禁了;搬一下上一篇的代码,后面学习记录更新
python版本
代码
# _*_coding:utf-8_*_
# create by Jucw on 2021/11/24 11:44
import requests
import bs4
import re
import pandas as pd # 存表格
n = 66 # 估计大概多少个教师
# 存储数据,这是对于每个老师的个人信息不是统一的,将没有的信息用空字符串填充
result = {"姓名": [""]*n,
"职称": [""]*n,
"系、研究所":[""]*n,
"研究领域":[""]*n,
"办公电话":[""]*n,
"电子邮件":[""]*n,
"讲授课程":[""]*n,
"个人主页":[""]*n,
"办公地点":[""]*n
}
# 网址
url = ""
# 网址设置了反爬虫,添加请求头模拟浏览器登录
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0'
}
# 请求数据
r = requests.get(url,headers=headers)
# 设置编码方式,否则出现乱码
r.encoding='utf-8'
# 解析
html = bs4.BeautifulSoup(r.text, "html.parser")
# 找到网页标签为 "ul" 下 class_="sdfasdjsf clearfloat" 下的所有 "li" 列表标签 每个列表代表一个老师
all_teacher = html.find("ul", class_="sdfasdjsf clearfloat").find_all("li")
# count 代表第几个老师,用于将数据写入到字典对应的位置
count = 0
for data in all_teacher:
zhichenk = data.find("div", class_="fasf").get_text() # 找到div class_="fast" 教授这个块
name = data.find("div", class_="mclb") # 找到对应的"mclb"类
for j in range(len(name)): # 循环每个老师 第一次进入的是教授这个列表的老师,第二次进入副教授,第三次进入讲师
k = j*2+1 # 这个是网页是每个老师信息出现之后会空一行,所以有用的信息在奇数行下
if k>=len(name): # 越界退出
break
a = name.contents[k] # 获取这一行的信息
m_href = a.attrs['href'] # 找到进入老师详细信息的链接
xinming = a.attrs['title'] # 这里通过debug 发现title 属性是教师名称
result["姓名"][count] = xinming # 在字典对应位置写入
m_href = ""+m_href[3:] # 网址前缀+提取网址
r1 = requests.get(m_href, headers=headers) # 请求新的链接进入信息页面
r1.encoding='utf-8'
bs1 = bs4.BeautifulSoup(r1.text, 'html.parser')
sour = bs1.find('div', id='vsb_content').find_all('p') # 信息在id 为"vsb_content" 的段内
for x in sour: # 遍历每个段
inflag = count
str = x.text # 获取文本信息
str = str.lstrip() # 去除信息的左空格
if str.count(":") >= 2: # 这一步判断是因为网页的信息有部分没有规矩,不能直接提取
s = str.split(" ") # 取出字符串前后空格
for i in s:
title = i.split(":") # 按照: 进行分割字符串
if len(title) == 1: # 空字符
continue
if title[0] == "职务":
result["职称"][inflag] = title[1]
elif title[0] == "电子邮箱" or title[0] == "个人邮箱":
result["电子邮件"][inflag] = title[1]
elif title[0] == "讲述课程":
result["讲授课程"][inflag] = title[1]
elif title[0] == "部门":
result["系、研究所"][inflag] = title[1]
else:
result[title[0]][inflag] = title[1]
continue
str = "".join(str.split()) # 去除字符串中的空格
if str == 'n' or str == '' or len(str)==1 or str == 'rn' or str == 'xa0xa0xa0': # 去除无关信息
continue
str = str.strip() # 去除空格
title = str.split(":") # 正常匹配按照冒号进行分割
if title[0] == "职务":
result["职称"][inflag] = title[1]
elif title[0] == "电子邮箱" or title[0] == "个人邮箱":
result["电子邮件"][inflag] = title[1]
elif title[0] == "讲述课程":
result["讲授课程"][inflag] = title[1]
elif title[0] == "部门":
result["系、研究所"][inflag] = title[1]
else:
result[title[0]][inflag]= title[1] # 不是特殊情况按照字典进行填写
infalg = j
count = count + 1 # 提取下一个老师信息
df = pd.Dataframe(result) #将字典使用格式转换
df.to_csv("jiaoshi1.csv", encoding="utf_8_sig") # 保存信息 防止csv 产生乱码


![[python&java爬虫实战]-爬取学院老师信息之-java版本&python版本 [python&java爬虫实战]-爬取学院老师信息之-java版本&python版本](http://www.mshxw.com/aiimages/31/618864.png)
