1. 目的
利用爬虫抓取信息:今年只招收了一名学生的导师的教师主页中的研究方向。
2. 准备
- 准备一个excel表单,含有每个学生对应的导师
- 安装chrome driver和selenium (准备 Chrome 浏览器)
参考:https://blog.csdn.net/zywmac/article/details/137470787
3. 思路
- 先在excel表单中用公式筛选出符合条件的导师姓名
- 使用selenium模拟浏览器动作搜索每个导师的教师主页,抓取”研究领域“的文本内容
4. 过程
1. excel中使用公式进行预处理
- 假设导师姓名都在A列,从 A2 开始。在 B2 单元格中输入以下公式,然后向下拖动填充公式到其他单元格:
=COUNTIF(A:A, A2)
计算 A 列中每个名字出现的次数。 - 提取只出现一次的名字,在 C2 单元格中输入以下公式:
=IF(B2=1, A2, "")
然后向下填充公式,显示出现次数为 1 的名字。(该列改名为”导一“)
2. python环境内操作爬虫
- 准备数据
df = pd.read_excel("硕士对应导师信息表.xlsx")
df = df.dropna()["导一"]
- 配置 Selenium WebDriver (确保你已经下载并配置好 ChromeDriver 或其他浏览器驱动)
driver = webdriver.Chrome() # 如果你用的是 Chrome 浏览器
driver.get("https://www.bing.com")
# 定义一个空列表,用来存储搜索结果地址
results = []
time.sleep(2) # 等待页面加载
- 模拟浏览器动作搜索导师信息,以哈尔滨工业大学的导师为例,搜索关键词条"导师名字-哈尔滨工业大学教师个人主页 - HIT"
# 遍历每个名字并进行搜索
for name in df['导一']:
search_query = f"{name} - 哈尔滨工业大学教师个人主页 - HIT"
# 找到 Bing 搜索框并输入查询内容
search_box = driver.find_element(By.NAME, "q")
search_box.clear()
search_box.send_keys(search_query)
search_box.send_keys(Keys.RETURN)
time.sleep(2) # 等待页面加载
# 获取第一个搜索结果的地址
try:
first_result = driver.find_element(By.CSS_SELECTOR, "li.b_algo h2 a")
first_result_url = first_result.get_attribute("href")
except Exception as e:
first_result_url = "未找到结果"
results.append(first_result_url)
time.sleep(1) # 等待页面加载
# 将结果添加到 DataFrame 新的一列
df['url'] = results
# 关闭浏览器
driver.quit()
# 显示带有新列的 DataFrame
print(df)
- 随便进入一个导师的教师主页,右键查看HTML源码,观察"研究方向"在哪个元素内。以哈尔滨工业大学的导师为例,一般导师的研究领域在第二个div class="part_box"中的div class="editor_content"中。
观察可知,这些div被伪元素::before ::after包裹,为了消除其对获取文本的影响,可以使用
content = driver.execute_script("return window.getComputedStyle(arguments[0], '::before').getPropertyValue('content') + arguments[0].textContent + window.getComputedStyle(arguments[0], '::after').getPropertyValue('content');", div_element)
完整代码:
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time
# 准备数据
df = pd.read_excel("硕士信息大表(学生版).xlsx")
df = df.dropna()["导一"]
# 配置 Selenium WebDriver (确保你已经下载并配置好 ChromeDriver 或其他浏览器驱动)
driver = webdriver.Chrome() # 如果你用的是 Chrome 浏览器
driver.get("https://www.bing.com")
# 定义一个空列表,用来存储搜索结果地址
results = []
time.sleep(2) # 等待页面加载
# 遍历每个名字并进行搜索
for name in df['导一']:
search_query = f"{name} - 哈尔滨工业大学教师个人主页 - HIT"
# 找到 Bing 搜索框并输入查询内容
search_box = driver.find_element(By.NAME, "q")
search_box.clear()
search_box.send_keys(search_query)
search_box.send_keys(Keys.RETURN)
time.sleep(2) # 等待页面加载
# 获取第一个搜索结果的地址
try:
first_result = driver.find_element(By.CSS_SELECTOR, "li.b_algo h2 a")
first_result_url = first_result.get_attribute("href")
except Exception as e:
first_result_url = "未找到结果"
results.append(first_result_url)
time.sleep(1) # 等待页面加载
# 将结果添加到 DataFrame 新的一列
df['url'] = results
# 关闭浏览器
driver.quit()
# 显示带有新列的 DataFrame
print(df.head(10))
# 设置Chrome选项
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式,不打开浏览器窗口
chrome_options.add_argument("--disable-gpu") # 如果系统不支持GPU加速,禁用它
chrome_options.add_argument("--no-sandbox") # 必要时禁用沙箱
# 指定chromedriver的路径
service = Service() # 请将/path/to/chromedriver替换为你的chromedriver路径
driver = webdriver.Chrome(service=service, options=chrome_options)
# 用于存储每个页面的内容
content_list = []
try:
for index, row in df.iterrows():
url = row["url"]
driver.get(url)
try:
# 等待页面加载完成,最长等待时间10秒
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "part_box"))
)
# 获取带有class="editor_content"的div内容
part_boxes = driver.find_elements(By.CLASS_NAME, 'part_box')
if len(part_boxes) < 2:
print(None)
content_list.append(None) # 如果没有第二个 'part_box',返回 None
continue
second_part_box = part_boxes[1]
div_element = second_part_box.find_element(By.CLASS_NAME, 'editor_content')
# 获取文本内容,包括伪元素
content = driver.execute_script("return window.getComputedStyle(arguments[0], '::before').getPropertyValue('content') + arguments[0].textContent + window.getComputedStyle(arguments[0], '::after').getPropertyValue('content');", div_element)
# 将内容添加到列表
content_list.append(content)
except Exception as e:
print(f"抓取 {url} 时出错:{e}") # 如果出现错误,打印错误信息
content_list.append(None)
finally:
driver.quit()
# 将内容保存回DataFrame中
df['editor_content'] = content_list
# 输出结果
print(df.head(10))
5. 遇到的问题
- ValueError: Timeout value connect was ……, but it must be an int, float or None
解决方法:selenium库和urllib3库版本不兼容,将urllib3版本降低。
参考:https://blog.csdn.net/weixin_60535956/article/details/131660133 - ChromeDriver与chrome浏览器不兼容
解决方法:更新ChromeDriver
参考:https://blog.csdn.net/IT_lw/article/details/121658468 - 不同导师的主页源码中,相同的板块class不同,内容顺序不同,有些缺乏有效信息,给爬取工作带来极大的挑战性。我无法解决这些问题,所以选择无视这些缺失数据。Anyway,我很想知道哈尔滨工业大学这个教师主页网站是谁开发维护的。
6. 参考
- https://blog.csdn.net/zywmac/article/details/137470787
- https://blog.csdn.net/weixin_60535956/article/details/131660133