数据采集作业1

代码源:https://gitee.com/wsmlhqqwwn/LH/tree/master/作业1
1.作业①:
要求:用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020)的数据,屏幕打印爬取的大学排名信息。
1.1作业代码和图片:

import requests
from bs4 import BeautifulSoup
import sys 

# --- 1. 获取网页 ---
url = 'http://www.shanghairanking.cn/rankings/bcur/2020'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}

# 打印提示信息
print(f"正在抓取: {url} ...")

try:
    # 发送请求
    response = requests.get(url, headers=headers, timeout=10)
    # 如果状态码不是200,则引发异常
    response.raise_for_status() 
    # 设置编码 (按你之前的要求)
    response.encoding = "utf-8"
    data = response.text
except Exception as e:
    # 打印错误并退出
    print(f"错误:网页请求失败: {e}", file=sys.stderr)
    sys.exit(1)

print("网页获取成功,正在解析...")

# --- 2. 解析数据 ---
# 使用 'lxml' 解析器
soup = BeautifulSoup(data, 'lxml')

# 找到表格主体 <tbody>
table_body = soup.find('tbody')

# 检查是否找到了 <tbody>
if not table_body:
    print("错误:在HTML中未找到 <tbody> 标签。网站结构可能已改变。", file=sys.stderr)
    sys.exit(1)

# 找到 <tbody> 中所有的 <tr> (行)
rows = table_body.find_all('tr')

if not rows:
    print("错误:在 <tbody> 中未找到 <tr> 标签 (数据行)。", file=sys.stderr)
    sys.exit(1)

print(f"解析成功,找到 {len(rows)} 行数据。")
print("-" * 20)

# --- 3. 按要求打印 ---
# 打印表头 (作业①要求) [cite: 5, 6]
print("排名,学校名称,省市,学校类型,总分")

# 遍历所有行
for row in rows:
    # 找到行内所有 <td> 单元格
    cells = row.find_all('td')
    
    # 提取数据 (确保有5列)
    if len(cells) >= 5:
        rank = cells[0].text.strip()
        school_name = cells[1].get_text(strip=True)
        region = cells[2].text.strip()
        school_type = cells[3].text.strip()
        total_score = cells[4].text.strip()
        
        # 按作业格式打印 [cite: 6]
        print(f"{rank},{school_name},{region},{school_type},{total_score}")

print("-" * 20)
print("任务完成。")

QQ20251027-195725
1.2 作业1:心得体会
通过这次实验,我成功掌握了使用Python进行网页爬虫的基本流程。
1.分析目标网页: 首先,使用浏览器的F12开发者工具,审查了目标网址(http://www.shanghairanking.cn/rankings/bcur/2020)的页面源代码。我发现所有的排名数据都很快地放在一个标签里面,每一行是一个标签,每一格数据都是一个标签。
2.获取网页(Requests): 我使用requests.get()方法,并设置了headers来模拟浏览器访问,成功获取到了完整的网页HTML源代码。
3.解析网页(BeautifulSoup): 接下来,我使用BeautifulSoup(html_text, 'html.parser')将获取到的 HTML 文本转换成一个 BeautifulSoup 对象。这使我能够方便地用标签来搜索数据。
4.定位与提取数据: 我利用soup.find('tbody')来定位到表格的主体,然后用find_all('tr')遍历表格中的每一行。在每一行中,我再find_all('td')用来获取所有单元格的列表。最后,我通过索引(如cells[0],cells[1])提取出排名、学校名称、省市、类型和总分,并使用.get_text(strip=True)来确保提取的数据是干净的纯文本。
5.主要收获:
我学会了requests库和BeautifulSoup库的良好工作流程:requests负责“下载”网页,BeautifulSoup负责“解析”和“查找”。掌握了如何使用浏览器F12工具来分析网页结构,这是爬虫成功的关键前提。学会了使用find()、find_all()等核心方法来精确定位并提取HTML标签中的内容。
2.作业②:
要求:用requests和re库方法设计某个商城(自已选择)商品比价定向爬虫,爬取该商城,以关键词“书包”搜索页面的数据,爬取商品名称和价格。
2.1作业代码和图片:

import requests
import re
import sys
def get_display_width(s):
    width = 0
    for char in s:
        width += 2 if ord(char) > 255 else 1
    return width

def pad_str(s, width, align='left'):
    current_width = get_display_width(s)
    padding_size = max(0, width - current_width)
    padding = " " * padding_size
    return padding + s if align == 'right' else s + padding
# 定义请求参数和URL
url = "http://search.dangdang.com"
keyword = '书包'
params = {'key': keyword, 'page_index': 1} 

# 模拟浏览器 User-Agent
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}

# 1. 获取网页 
try:
    response = requests.get(url, headers=headers, params=params, timeout=30)
    response.raise_for_status() 
    response.encoding = 'gb2312'
    html_data = response.text
except requests.exceptions.RequestException as e:
    sys.exit(1)

#  2. 正则表达式提取数据 
# 定义价格和商品名的匹配规则
pattern = re.compile(
    r'<span class="price_n">&yen;(\d+(?:\.\d+)?)</span>.*?<a title="(.+?)"'
)

# 使用 re.findall 查找所有匹配项
results = re.findall(pattern, html_data)

if not results:
    sys.exit(1)

# 打印输出
W_NO = 6
W_PRICE = 10
W_NAME = 70

# 打印表格分隔线和表头
header_line = (
    "序号".center(W_NO) + " | " + 
    "价格".center(W_PRICE) + " | " +
    "商品名".ljust(W_NAME)
)
print("-" * (W_NO + W_PRICE + W_NAME + 6)) 
print(header_line)
print("-" * (W_NO + W_PRICE + W_NAME + 6))

# 遍历结果并格式化打印
for index, item in enumerate(results, start=1):
    price = item[0].strip()
    name = item[1].strip()
    
    # 格式化每一行数据
    data_line = (
        str(index).center(W_NO) + " | " +
        price.ljust(W_PRICE) + " | " +
        name[:W_NAME].ljust(W_NAME)
    )
    print(data_line)

# 打印表格底部
print("-" * (W_NO + W_PRICE + W_NAME + 6))

2
2.2 作业2:心得体会
通过完成本次商品比价爬虫实验,我深入理解了结合使用requests库和re(正则表达式)库来定向爬取静态网页中的特定数据。
1.确定目标与参数: 我选择了稳定结构的当当网作为目标商城,并确定了搜索关键词“书包”。通过分析当当网的URL结构,我成功构建了包含key和page_index的请求参数,确保能够获取到正确的商品列表页面内容。
2.获取网页内容(请求): 我使用requests.get()方法发送HTTP请求,并设置了headers模拟浏览器访问。为了保证获取过程的稳定性,我设置了四个的超时时间。同时,为了保证中文正常显示,我将响应编码设置为gb2312。
3.核心技术:设计正则表达式(re): 本次实验的关键在于re高效使用。我编写了一个专业而的正则表达式模式,通过一个模式同时定位并提取商品名称和价格。利用非贪婪的(.+?)名称捕获了title属性中的商品。精确匹配了价格附近的HTML结构,并获取了¥符号后的数字和小数部分作为价格数据。最终,我通过re.findall()成功批量提取了所有商品的名称和价格。
4.主要收获:
掌握了requests库和re库的经典组合应用:requests负责下载原始HTML文本,然后re负责对原始文本进行精确的模式匹配和数据提取。学会了如何设计一个强大的、具有多个捕获组的正则表达式,以实现一次匹配同时提取多个数据项。掌握了通过设定headers和编码来保证爬虫的成功率和数据的正确性。学会了利用 Python 的字符串删除技巧,使最终的终端输出结果呈现出清晰、美观的表格样式。
3.作业③:
要求:爬取一个给定网页( https://news.fzu.edu.cn/yxfd.htm)或者自选网页的所有JPEG、JPG或PNG格式图片文件
输出信息:将自选网页内的所有JPEG、JPG或PNG格式图片件保存在一个文件夹中
代码和结果:

import requests
from bs4 import BeautifulSoup
import os
import re
import sys
from urllib.parse import urljoin

# 定义目标URL和保存图片的文件夹名
TARGET_URL = "https://news.fzu.edu.cn/yxfd.htm"
SAVE_DIR = "web_images_full"  # 使用新的文件夹名避免覆盖旧文件


def get_absolute_url(base_url, relative_url):
    """将相对URL转换为完整的绝对URL。"""
    if relative_url.lower().startswith('http') or relative_url.lower().startswith('https'):
        return relative_url
    return urljoin(base_url, relative_url)


def crawl_and_save_images(url, save_directory):
    # 1. 检查或创建保存图片的文件夹
    if not os.path.exists(save_directory):
        os.makedirs(save_directory)
        print(f"创建文件夹: {save_directory}")

    # 2. 获取网页内容
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
        }
        response = requests.get(url, headers=headers, timeout=15)
        response.raise_for_status()
        response.encoding = response.apparent_encoding
        html_data = response.text
        print(f"成功获取网页内容: {url}")
    except requests.exceptions.RequestException as e:
        print(f"错误:无法获取网页内容: {e}", file=sys.stderr)
        return

    # 3. 收集所有可能的图片链接

    # 使用集合(set)存储链接,自动去重
    image_urls = set()

    # --- 策略 A: 查找 <img> 标签 (BeautifulSoup) ---
    soup = BeautifulSoup(html_data, 'html.parser')
    for tag in soup.find_all('img'):
        src = tag.get('src')
        if src:
            image_urls.add(get_absolute_url(url, src))

    # --- 策略 B: 使用正则表达式查找 HTML 中的所有图片链接 ---
    # (关键步骤) 查找所有以 .jpg, .jpeg, .png 结尾的链接
    # re.I 忽略大小写
    pattern = re.compile(r'[\'\"](.*?)\.(jpe?g|png)[\'\"]', re.I)

    # 在整个 HTML 文本中查找
    for match in re.findall(pattern, html_data):
        # match 是一个元组,第一个元素是链接主体
        link = match[0] + "." + match[1]
        image_urls.add(get_absolute_url(url, link))

    # 4. 遍历链接并下载
    download_count = 0
    print(f"找到 {len(image_urls)} 个去重后的图片链接,开始下载...")

    for img_url in image_urls:
        filename = img_url.split('/')[-1].split('?')[0]
        file_path = os.path.join(save_directory, filename)
        if os.path.exists(file_path):
            continue

        # (关键步骤) 再次确认链接是否符合 jpg/jpeg/png 格式
        if not re.search(r'\.(jpe?g|png)$', img_url, re.I):
            continue

        try:
            # 下载图片内容 (使用 content 获取二进制数据)
            img_response = requests.get(img_url, timeout=10)
            img_response.raise_for_status()

            # 以二进制写入模式 ('wb') 保存文件
            with open(file_path, 'wb') as f:
                f.write(img_response.content)

            download_count += 1

        except requests.exceptions.RequestException:
            # 忽略下载失败的链接
            continue

    print("-" * 30)
    print(f"作业③ 任务完成。共成功下载了 {download_count} 张新图片到 '{save_directory}' 文件夹。")


if __name__ == "__main__":
    crawl_and_save_images(TARGET_URL, SAVE_DIR)

3

4

3.2 作业3:心得体会:
1.获取网页: 我使用了 requests.get() 方法,并设置了 headers 模拟浏览器,成功获取了目标网页(福大要闻)的 HTML 源代码。
2.全面提取图片链接(关键步骤): 我意识到,只抓取 标签会遗漏很多图片。为了爬取所有 JPEG、JPG 或 PNG 图片 ,我结合了两种策略:
3.使用 BeautifulSoup: 我先用 soup.find_all('img') 找到所有 标签,并提取它们的 src 属性。
4.使用 正则表达式 (re): 为了找到那些隐藏在 HTML 文本中、但不在 标签里的图片链接(例如 CSS 背景图),我额外使用 re.findall() 配合 r'.(jpe?g|png)' 规则,对整个 HTML 文本进行了全面搜索。
主要收获:
我学会了 BeautifulSoup 和 re 协同工作的爬虫策略:BeautifulSoup 擅长解析 HTML 结构(如 ),而 re 擅长在纯文本中匹配模式(如 *.jpg)。掌握了 urllib.parse.urljoin() 这个重要工具,它能帮我自动处理相对路径和绝对路径的拼接问题。理解了下载文件(如图片)和下载文本的核心区别:必须使用 response.content (二进制) 和 'wb' (二进制写入) 模式。

posted @ 2025-10-27 20:59  七年qn  阅读(2)  评论(0)    收藏  举报