数据采集与融合第一次作业
作业①
要求:
用requests
和BeautifulSoup
库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020 )的数据,屏幕打印爬取的大学排名信息。
输出信息:
排名 | 学校 | 省市 | 类型 | 总分 |
---|---|---|---|---|
1 | 清华大学 | 北京 | 综合 | 852.5 |
爬取大学排名
🌱实现思路:
- 页面结构分析:分析网页结构,发现排名数据在一个 HTML 表格中,每一行对应一所学校的相关信息,列 (
<td>
) 包含具体数据,如排名、学校名称、所属省市、学校类型和总分。 - 发送 HTTP 请求
- 解析 HTML 内容
- 提取和处理数据:每一行 (
<tr>
) 内部包含多个列 (<td>
),我们通过row.find_all('td')
提取所有列。
🎨主要代码:
import requests
from bs4 import BeautifulSoup
import re
def school_name_get(column_name):
# 正则匹配学校名称
tag = r'^[\u4e00-\u9fff]+'
school_name_raw = column_name.get_text(strip=True)
school_name = re.search(tag, school_name_raw).group(0)
return school_name
# 爬取网址
url = 'http://www.shanghairanking.cn/rankings/bcur/2020'
# 发送HTTP请求并获取网页内容
response = requests.get(url)
html = response.content
# 解析网页内容
soup = BeautifulSoup(html, 'lxml')
# 打印表头
print(f'{"排名":<4} {"学校名称":<20} {"省市":<6} {"学校类型":<6} {"总分":<6}')
# 找到表格行
rows = soup.find_all('tr')[1:]
# 遍历每一行并提取数据
for row in rows:
columns = row.find_all('td')
if len(columns) < 5: # 防止某些行没有足够的列
continue
# 提取每列数据
rank = columns[0].get_text(strip=True)
school_name = school_name_get(columns[1])
province_city = columns[2].get_text(strip=True)
school_type = columns[3].get_text(strip=True)
total_score = columns[4].get_text(strip=True)
# 打印数据
print(f'{rank:<4} {school_name:<20} {province_city:<6} {school_type:<6} {total_score:<6}')
运行结果:
心得体会
本次爬虫项目不仅巩固了我对 requests
和 BeautifulSoup
的使用技巧,还让我认识到分析网页结构的重要性以及如何编写健壮的爬虫代码。整个过程加强了我对正则表达式的应用理解,特别是在处理不规则数据时,正则表达式是一个高效的工具。此外,如何处理和显示爬取的数据也是一个重要的环节,清晰、美观的输出可以让数据更易于理解。
作业②
要求:
用requests
和re
库方法设计某个商城(自已选择)商品比价定向爬虫,爬取该商城,以关键词“书包”搜索页面的数据,爬取商品名称和价格。
输出信息:
序号 | 价格 | 商品名 |
---|---|---|
1 | 65.00 | 新款儿童书包 |
2 |
爬取商品名称和价格
🌱实现思路:
- 发送 HTTP 请求并获取网页内容:使用
requests
获取网页 HTML 数据。 - 解析 HTML 结构,提取商品名称和价格:匹配包含商品名称的
<p class="name">
标签和包含价格的<span class="price_n">
标签。 - 格式化输出:遍历商品数据并以表格形式输出,保证每列数据整齐显示。
🎨主要代码:
import requests
import re
# 设置请求头,模拟浏览器行为
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
}
# 目标URL:商城的搜索页面,搜索关键词“书包”
url = "http://search.dangdang.com/?key=%CA%E9%B0%FC&act=input"
try:
# 发送请求并获取响应数据
response = requests.get(url, headers=headers)
response.encoding = response.apparent_encoding # 设置编码,避免乱码
data = response.text # 获取网页的HTML内容
# 定义正则表达式匹配商品名称和价格
# 匹配商品名称:匹配 <p class="name"> 标签中的 a 标签内容
name_pattern = r'<p class="name"[^>]*><a[^>]*>(.*?)</a></p>'
# 匹配价格:匹配 <span class="price_n">¥xxx.xx</span>
price_pattern = r'<span class="price_n">([^<]+)</span>'
# 使用正则表达式查找所有匹配的商品名称和价格
names = re.findall(name_pattern, data)
prices = re.findall(price_pattern, data)
# 去除商品名称中的 HTML 标签,如 <font>
names = [re.sub(r'<[^>]+>', '', name) for name in names]
# 去除价格中的人民币符号(¥ 或 ¥)
prices = [price.replace('¥', '').replace('¥', '').strip() for price in prices]
# 输出表头
print(f"{'序号':<4}\t{'价格':<6}\t{'商品名'}")
# 组合商品名称和价格并输出结果
products = list(zip(names, prices))
for index, product in enumerate(products, start=1):
print(f"{index:<4}\t{product[1]:<6}\t{product[0]}")
except Exception as err:
print(f"An error occurred: {err}")
运行结果:
心得体会
在这次爬虫项目中,我加强了对 requests
和正则表达式的理解,还学习了如何处理网页中的多余 HTML 标签和符号的能力。也意识到当网页结构发生变化时(如标签名改变、属性增加或减少),正则表达式会变得脆弱,需要频繁调整。这让我更加认识到,解析复杂网页时,使用 BeautifulSoup
或 lxml
等专门的 HTML 解析工具会更加灵活可靠。
作业③
要求:
爬取一个给定网页( https://xcb.fzu.edu.cn/info/1071/4481.htm)或者自选网页的所有JPEG和JPG格式文件
输出信息:
将自选网页内的所有JPEG和JPG文件保存在一个文件夹中
爬取给定网页所有JPEG,JPG格式文件
🌱实现思路:
- 发送 HTTP 请求:使用
requests
库发送请求,获取网页的 HTML 内容。 - 解析网页:使用
BeautifulSoup
解析 HTML,提取所有图片链接。 - 筛选图片格式:通过检查图片链接的后缀,筛选出所有 JPEG 和 JPG 格式的文件。
- 下载图片:使用
requests
库下载这些图片并保存在指定的文件夹中。
🎨主要代码:
import os
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
# 设置要爬取的网页
url = "https://news.fzu.edu.cn/yxfd.htm"
# 创建存储图片的文件夹
folder = "downloaded_images"
if not os.path.exists(folder):
os.makedirs(folder)
# 设置请求头,模拟浏览器
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
}
# 发送请求并获取网页内容
response = requests.get(url, headers=headers)
response.raise_for_status() # 如果请求失败,则抛出异常
soup = BeautifulSoup(response.text, "lxml")
# 查找所有图片链接
img_tags = soup.find_all("img")
# 筛选出JPEG和JPG图片并下载
for img in img_tags:
img_url = img.get("src")
if img_url: # 如果图片有 src 属性
# 拼接完整的URL(有些图片链接可能是相对路径)
full_img_url = urljoin(url, img_url)
# 检查是否是JPEG或JPG格式的图片
if full_img_url.lower().endswith((".jpg", ".jpeg")):
# 下载图片
img_data = requests.get(full_img_url).content
# 生成图片文件名(从 URL 中提取文件名)
img_name = os.path.join(folder, full_img_url.split("/")[-1])
# 保存图片
with open(img_name, "wb") as f:
f.write(img_data)
print(f"已下载图片: {img_name}")
print(f"所有JPEG和JPG图片已保存在文件夹 '{folder}' 中。")
运行结果:
心得体会
整个过程让我进一步理解了爬虫的核心流程:请求网页、解析数据、筛选目标内容、处理并保存。同时,当图片数量较多时,爬虫程序需要考虑效率问题,例如可以加入多线程或异步处理来加速图片的下载。