2023数据采集与融合技术作业一

作业①

1.大学排名爬取

要求

用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020 )的数据,屏幕打印爬取的大学排名信息。

排名 学校名称 省市 学校类型 总分
1 清华大学 北京 综合 852.5
2......

代码

点击查看代码
import requests
from bs4 import BeautifulSoup
import re

# 目标网页:上海软科中国大学排名
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/85.0.4183.121 Safari/537.36"
}

# 发送请求,编码为utf-8
response = requests.get(url, headers=headers)
response.encoding = "utf-8"
# 使用 BeautifulSoup 解析网页内容,指定解析器为 html.parser
soup = BeautifulSoup(response.text, "html.parser")
# 选择表格中的所有行(tr),tbody 表示表格主体
rows = soup.select("tbody tr")
# 打印表头
print(f"{'排名':<5}{'学校名称':<15}{'省市':<10}{'学校类型':<10}{'总分':<10}")
# 遍历每一行数据,获取当前行中的所有单元格,确保这一行至少有 5 列数据(排名、学校、地区、类型、分数)
for row in rows:
    cols = row.find_all("td")
    if len(cols) >= 5:
        # 提取排名,去掉多余空格
        rank = cols[0].get_text(strip=True)
        # 学校名称可能在 <a><span> 标签中,如果存在 span 标签,直接取文本,否则直接取 td 的文本,并用正则去掉非中文字符
        span = cols[1].select_one("a span")
        if span:           
            name = span.get_text(strip=True)
        else:
            raw_name = cols[1].get_text(strip=True)
            name = re.sub(r"[^\u4e00-\u9fff]", "", raw_name)
        # 去掉学校名称中的“ 双一流 ”字样
        # 去掉“ 双一流 ”以及可能存在的空格
        name = re.sub(r"\s*双一流\s*", "", name)
        # 提取省市、学校类型、总分
        province = cols[2].get_text(strip=True)
        category = cols[3].get_text(strip=True)
        score = cols[4].get_text(strip=True)
        # 格式化输出每一行数据
        print(f"{rank:<5}{name:<15}{province:<10}{category:<10}{score:<10}")

实验结果

image

2.心得体会

这段代码通过 requests 获取网页内容,用 BeautifulSoup 解析表格数据,再通过ccs选择器获取表格中的数据行,逐行提取需要的字段,最后用格式化输出整齐展示排名结果。在其中学会了运用find方法寻找tbody,同时结果发现学校名称有时包含额外的标签或“ 双一流 ”字样,我在事后运用re.sub将其去除,以达到格式要求。

作业②

1.商品价格爬取实验

要求

用requests和re库方法设计某个商城(自已选择)商品比价定向爬虫,爬取该商城,以关键词“书包”搜索页面的数据,爬取商品名称和价格。

序号 价格 商品名
1 65.00 xxx
2......

代码

点击查看代码
import requests
import re
import random
# 设置请求的URL,搜索书包
url = "http://search.dangdang.com/?key=%CA%E9%B0%FC&act=input"
try:
    # 发送请求,获取编码
    r = requests.get(url)
    r.encoding = r.apparent_encoding
except:
    print("fail")
# 获取网页的HTML源码
html = r.text
# 使用正则表达式提取商品列表所在的<ul>标签块
m = re.search('<ul class="bigimg cloth_shoplist".*?</ul>', html, re.S)
if not m:
    print("没找到商品")
# 将匹配到的<ul>部分HTML提取出来
html = m.group()
# 在<ul>中查找所有<li>标签
lis = re.findall("<li.*?</li>", html, re.S)
random.shuffle(lis)
i = 1
for li in lis:
    # 提取价格信息和商品名称
    p = re.search('<span class="price_n">&yen;(.*?)</span>', li)
    t = re.search('title="(.*?)"', li)
    if p and t:
        price = "¥" + p.group(1)
        name = t.group(1)
        print(f"{i}. {name}  ——  {price}")
    i += 1

实验结果

屏幕截图 2025-10-18 172825

2.心得体会

在写代码时我原本想用淘宝和京东来进行爬取,结果却都被反爬导致没有结果,最后没有办法在查询网络后选择了当当网并成功爬取。这段代码中我选取了通过 requests 库向当当网发送搜索请求,获取“书包”的搜索结果页面源码,然后利用正则表达式提取商品列表ul中li的每个标签,从中解析出商品的价格和名称,并以“序号 商品 价格”的表格形式打印出来。

作业③

1.福大网页图片下载

要求

爬取一个给定网页(https://news.fzu.edu.cn/yxfd.htm)或者自选网页的所有JPEG、JPG或PNG格式图片文件,将自选网页内的所有JPEG、JPG或PNG格式文件保存在一个文件夹中

代码

点击查看代码
import re
import urllib.request
import os

# 要爬取的网页列表,共6页
pages = [
    "https://news.fzu.edu.cn/yxfd.htm",
    "https://news.fzu.edu.cn/yxfd/1.htm",
    "https://news.fzu.edu.cn/yxfd/2.htm",
    "https://news.fzu.edu.cn/yxfd/3.htm",
    "https://news.fzu.edu.cn/yxfd/4.htm",
    "https://news.fzu.edu.cn/yxfd/5.htm",
]

# 用来存储所有图片链接
allpics = []

# 遍历每个网页
for p in pages:
    print("正在爬:", p)
    # 构造请求
    req = urllib.request.Request(p, headers={"User-Agent":"Mozilla/5.0"})
    # 打开网页
    res = urllib.request.urlopen(req)
    # 读取网页内容
    html = res.read().decode("utf-8","ignore")

    # 使用正则表达式匹配所有 jpg 图片链接
    pat = re.compile(r'src="([^"]+?\.jpg)"', re.IGNORECASE)
    links = pat.findall(html)
    print("找到", len(links), "张")

    # 提取网页的域名部分
    domain = re.match(r"(https?://[^/]+)", p).group(1)
    newlinks = []
    for l in links:
        # 如果是完整的 http 链接,直接使用
        if l.startswith("http"):
            newlinks.append(l)
        # 如果是以 / 开头的相对路径,加上域名
        elif l.startswith("/"):
            newlinks.append(domain + l)
        # 否则认为是相对路径,加上当前页面所在目录
        else:
            newlinks.append(p.rsplit("/",1)[0] + "/" + l)

    # 将处理好的链接加入总列表
    allpics += newlinks

# 去重,避免重复下载相同图片
allpics = list(set(allpics))

print("总共", len(allpics), "张, 开始下载...")
# 下载图片并保存到 image 文件夹
i = 1
for u in allpics:
    try:
        fname = "image/img_" + str(i) + ".jpg"
        # 下载图片
        urllib.request.urlretrieve(u, fname)
        print("ok:", fname)
        i += 1
    except:
        # 如果下载失败,打印失败的链接
        print("fail:", u)

结果

屏幕截图 2025-10-18 194648

屏幕截图 2025-10-18 203103

2.心得体会

在爬取图片时遇到了下载多张图片的问题,通过set进行去重后解决,同时爬取图片的链接不是标准的url,要加http。

posted @ 2025-10-18 20:36  abc。  阅读(5)  评论(0)    收藏  举报