[pythonjava爬虫实战]-爬取学院老师信息之-java版本python版本
文章目錄
- Java 版本
- 思路:
- 預備工作:
- 簡述
- 代碼
- python版本
- 代碼
這個實戰文章僅作為自己學習筆記記錄;使用java和python爬取相同的內容,由于爬取內容涉及個人信息,去除了敏感信息,作為學習記錄!python實戰那篇被官方禁了 苦笑
Java 版本
思路:
預備工作:
導包
使用Maven創建項目;
導包的時候直接在pom.xml添加依賴即可完成導包;不需要下載到本地添加;
Jsoup 包依賴
jxl 包依賴
<dependency><groupId>net.sourceforge.jexcelapi</groupId><artifactId>jxl</artifactId><version>2.6.12</version></dependency>添加完刷新一下
也可以下載到本地(針對不是Maven項目)
jxl 包下載官網
簡述
java:
提取到信息之后保存到表格的過程,第一思路是跟寫python那一篇一樣使用字典,但是查了一些資料,實現不了;
第二個想到的是一邊查找一邊寫入,這個過程就要先創建出一個工作表,就需要導入jxl包,這個是表單創建需要的包;
在去除提取信息的問號:
java:str.resplaceAll(“[?]”,"");使用這個一直去不掉?,
如果使用python str.strip("?") 直接將問號去掉;
去除空格:
java: str.trim() //去除首尾空格
python : str.strip() # 默認去除空格
字符串子串:
java : str.substring(beg,end); //需要開頭和尾部的位置
python :直接使用切片;
| 文件格式 | 文本 | 二進制文件 |
| 全稱 | 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 = "姓名,職稱,系、研究所,研究領域,講授課程,辦公電話,電子郵箱,辦公地點,個人主頁"; // 定義表格的TitleWritableWorkbook 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<titleElement.get(i).children().size();j++) // 遍歷每個表單的每個老師{String herf = titleElement.get(i).children().get(j).attr("href"); //獲取每個老師的信息鏈接String teacher_name = titleElement.get(i).children().get(j).attr("title"); // 獲取名稱Label label = new Label(0,teacherNum,teacher_name); sheet.addCell(label); //添加到表單里String schoolHref = ""; //網址前綴String contentHerf = schoolHref + herf.substring(2,herf.length()); // 拼接成新的鏈接Document contentDoc = Jsoup.connect(contentHerf).get(); // 獲取新的鏈接內容Element contentElement = contentDoc.getElementById("vsb_content"); //定位Idfor(int p =0;p<contentElement.select("p").size();p++) // 循環新的段落,每個段落為職稱,郵箱等等;{String pcontent = contentElement.select("p").get(p).text(); //獲取段落文本String s1 = ":";if(pcontent.contains(s1)) //匹配中文冒號是否在字符串中{String reg = "[^\u4e00-\u9fa5a-zA-Z1-9:.( )/:,@]"; // 匹配除了中文字母數字等等pcontent.trim(); // 去除字符串前后空格pcontent = pcontent.replaceAll(reg, ""); //將上面這些存在的之外的用空字符進行替換String[] pcon = pcontent.split(":"); //按照中文冒號進行劃分if(pcon[0].equals("職稱")||pcon[0].equals("職務")) //進行判讀之后填寫入表格{Label zhiwu = new Label(1,teacherNum, pcon[1]); //表示第1列第teacherNum行;sheet.addCell(zhiwu);}if(pcon[0].equals("系研究所")||pcon[0].equals("部門")){Label danwei = new Label(2,teacherNum, pcon[1]); //第二列第teacherNum行sheet.addCell(danwei);}if(pcon[0].equals("研究領域")){Label yanjiu = new Label(3,teacherNum, pcon[1]);sheet.addCell(yanjiu);}if(pcon[0].equals("講授課程")||pcon[0].equals("講述課程")){Label course = new Label(4,teacherNum, pcon[1]);sheet.addCell(course);}if(pcon[0].equals("辦公電話")){Label phone = new Label(5,teacherNum, pcon[1]);sheet.addCell(phone);}if(pcon[0].equals("電子郵箱")||pcon[0].equals("電子郵件")||pcon[0].equals("個人郵箱")){Label email = new Label(6,teacherNum, pcon[1]);sheet.addCell(email);}if(pcon[0].equals("辦公地點")){Label address = new Label(7,teacherNum, pcon[1]);sheet.addCell(address);}if(pcon[0].equals("個人主頁")){Label personalWeb = new Label(8,teacherNum, pcon[1]);sheet.addCell(personalWeb);}}else {}}teacherNum +=1; //下一位老師}}}catch (IOException e){e.printStackTrace();}book.write();book.close();}}由于之前這篇被官方認為是違規博文,所以之前的學習日記被禁了;搬一下上一篇的代碼,后面學習記錄更新
python版本
代碼
# _*_coding:utf-8_*_ # create by Jucw on 2021/11/24 11:44import 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 = 0for 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): # 越界退出breaka = 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 = countstr = x.text # 獲取文本信息str = str.lstrip() # 去除信息的左空格if str.count(":") >= 2: # 這一步判斷是因為網頁的信息有部分沒有規矩,不能直接提取s = str.split(" ") # 取出字符串前后空格for i in s:title = i.split(":") # 按照: 進行分割字符串if len(title) == 1: # 空字符continueif 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]continuestr = "".join(str.split()) # 去除字符串中的空格if str == '\n' or str == '' or len(str)==1 or str == '\r\n' or str == '\xa0\xa0\xa0': # 去除無關信息continuestr = 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 = jcount = count + 1 # 提取下一個老師信息 df = pd.DataFrame(result) #將字典使用格式轉換 df.to_csv("jiaoshi1.csv", encoding="utf_8_sig") # 保存信息 防止csv 產生亂碼總結
以上是生活随笔為你收集整理的[pythonjava爬虫实战]-爬取学院老师信息之-java版本python版本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [python Cookbook]阅读笔
- 下一篇: 【实战】tensorflow 花卉识别