当前位置: 首页 > news >正文

102302125 苏琎宇 数据采集第1次作业

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

在分析网站的数据结构和请求方式后,发现无法像普通分页网页那样简单地循环请求分页数据,原因主要是:

数据是通过前端 JS 动态生成的

  • 网站使用 Nuxt.js(或类似 SPA 框架)渲染页面内容。
  • 页面里的数据(大学排名、详细信息等)并不是直接在 HTML 里,而是存储在一个 JS 对象里,例如:
__NUXT_JSONP__("/rankings/bcur/2020", function(...) { return { data: [...], fetch: {...} }})

image

  • 也就是说 每页的数据都在 JS 文件里预加载,浏览器解析 JS 后才渲染到页面。
  • 对于爬虫而言,直接请求 HTML 无法获取 JS 渲染后的内容。

因此要爬取到全部大学排名信息无法使用urllib.request和BeautifulSoup这种传统做法

网络抓包分析后发现有一个payload.js文件拥有全部的数据

image

使用console查看

image

可以使用这一个console命令下载到数据

image

image

import urllib.request                                                                
import re                                                                            
import csv                                                                           def fetch_html(url):                                                                 headers = {                                                                      "User-Agent": (                                                              "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "                             "AppleWebKit/537.36 (KHTML, like Gecko) "                                "Chrome/128.0.0.0 Safari/537.36"                                         )                                                                            }                                                                                req = urllib.request.Request(url, headers=headers)                               with urllib.request.urlopen(req, timeout=5) as resp:                             return resp.read().decode('gb2312', errors='ignore')                         def parse_products(html):                                                            """ 使用正则从 HTML 中提取书包商品名称和价格 """                                 li_blocks = re.findall(r'<li[^>]*?>(.*?)</li>', html, re.S)                      products = []                                                                    for li in li_blocks:                                                             name_match = re.search(r'title="([^"]+)"', li)                               price_match = re.search(r'<span class="price_n">\s*(.*?)\s*</span>', li)     if name_match and price_match:                                               name = name_match.group(1).strip()                                       price = price_match.group(1).replace('&yen;', '¥').strip()               products.append((name, price))                                           return products                                                                  def save_to_csv(products, filename="dangdang_bookbag.csv"):                          """ 保存为 CSV 文件 """                                                          with open(filename, "w", newline="", encoding="utf-8-sig") as file:              writer = csv.writer(file)                                                    writer.writerow(["序号", "价格", "商品名"])                                  for idx, (name, price) in enumerate(products, start=1):                      writer.writerow([idx, price, name])                                      print(f"\n✅ 数据已成功保存到文件:{filename}")                                  def main():                                                                          url = "https://search.dangdang.com/?key=%CA%E9%B0%FC&category_id=10009684#J_tab" print("开始爬取当当网“书包”商品数据...\n")                                       try:                                                                             html = fetch_html(url)                                                       products = parse_products(html)                                              print(f"共爬取到 {len(products)} 件有效商品,正在保存到CSV...")              save_to_csv(products)                                                        except Exception as e:                                                           print("❌ 爬取失败:", e)                                                    print("\n爬取任务结束!")                                                        if __name__ == "__main__":                                                           main()                                                                           

运行结果:
image

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

import urllib.request
import re
import csvdef fetch_html(url):headers = {"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/128.0.0.0 Safari/537.36")}req = urllib.request.Request(url, headers=headers)with urllib.request.urlopen(req, timeout=5) as resp:return resp.read().decode('gb2312', errors='ignore')def parse_products(html):""" 使用正则从 HTML 中提取书包商品名称和价格 """li_blocks = re.findall(r'<li[^>]*?>(.*?)</li>', html, re.S)products = []for li in li_blocks:name_match = re.search(r'title="([^"]+)"', li)price_match = re.search(r'<span class="price_n">\s*(.*?)\s*</span>', li)if name_match and price_match:name = name_match.group(1).strip()price = price_match.group(1).replace('&yen;', '¥').strip()products.append((name, price))return productsdef save_to_csv(products, filename="dangdang_bookbag.csv"):""" 保存为 CSV 文件 """with open(filename, "w", newline="", encoding="utf-8-sig") as file:writer = csv.writer(file)writer.writerow(["序号", "价格", "商品名"])for idx, (name, price) in enumerate(products, start=1):writer.writerow([idx, price, name])print(f"\n✅ 数据已成功保存到文件:{filename}")def main():url = "https://search.dangdang.com/?key=%CA%E9%B0%FC&category_id=10009684#J_tab"print("开始爬取当当网“书包”商品数据...\n")try:html = fetch_html(url)products = parse_products(html)print(f"共爬取到 {len(products)} 件有效商品,正在保存到CSV...")save_to_csv(products)except Exception as e:print("❌ 爬取失败:", e)print("\n爬取任务结束!")if __name__ == "__main__":main()

image

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

import re
import urllib.request
import os
from colorama import Fore, Style, initinit(autoreset=True)# ------------------------------
# 1. 下载网页
# ------------------------------
def get_html(url):headers = {"User-Agent": "Mozilla/5.0"}req = urllib.request.Request(url, headers=headers)with urllib.request.urlopen(req) as response:html = response.read().decode("utf-8", errors="ignore")return html# ------------------------------
# 2. 提取 JPG / JPEG / PNG 图片链接
# ------------------------------
def get_image_links(html, base_url):# 匹配 jpg, jpeg, png 图片链接pattern = re.compile(r'src="([^"]+\.(?:jpg|jpeg|png))"', re.IGNORECASE)links = pattern.findall(html)domain = re.match(r"(https?://[^/]+)", base_url).group(1)full_links = []for link in links:if link.startswith("http"):full_links.append(link)elif link.startswith("/"):full_links.append(domain + link)else:full_links.append(base_url.rsplit("/", 1)[0] + "/" + link)return list(set(full_links))# ------------------------------
# 3. 下载图片
# ------------------------------
def download_images(links, folder="images"):if not os.path.exists(folder):os.makedirs(folder)for i, url in enumerate(links, start=1):try:ext = os.path.splitext(url)[1].split('?')[0]  # 自动识别扩展名filename = os.path.join(folder, f"img_{i}{ext}")urllib.request.urlretrieve(url, filename)print(Fore.GREEN + f"下载成功: {filename}")except Exception as e:print(Fore.RED + f"下载失败: {url} ({e})")# ------------------------------
# 4. 主程序
# ------------------------------
if __name__ == "__main__":base_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",]all_links = []for page in base_pages:print(f"\n正在爬取页面: {page}")html = get_html(page)links = get_image_links(html, page)print(f"  找到 {len(links)} 张图片")all_links.extend(links)# 去重all_links = list(set(all_links))print(f"\n共提取 {len(all_links)} 张图片,开始下载...\n")download_images(all_links)print("\n✅ 所有图片下载完成!")                             

image

http://www.jsqmd.com/news/24766/

相关文章:

  • 哈希优化策略
  • 一站式开发速查表大全 - 覆盖主流编程语言与工具
  • GNU C和ANSI C的一些差异
  • gcc系编译器、调试器的应用和c/c++编译原理
  • JAVA FX初次使用并制作辅助工具指南
  • Day6综合案例1-体育新闻列表
  • 题解:AT_agc015_e [AGC015E] Mr.Aoki Incubator
  • SNP特征通道数是什么意思
  • CF1482E Skyline Photo
  • sqlserver 添加或修改字段
  • 最小瓶颈生成树
  • 小程序语音通话让智能设备会“说话”
  • 易基因: NG (IF29):颠覆认知!深圳仙湖植物园刘阳团队WGBS及超级泛基因组分析揭示苔藓植物基因家族比维管植物更丰富|项目文章
  • 2025年口碑好的工业制冷供应厂家推荐
  • 2025 年 150 吨地磅,180 吨地磅,200 吨地磅厂家最新推荐,产能、专利、环保三维数据透视!
  • MySql8.0公共表表达式『CTE』
  • 2025 年进口地磅,出口地磅,100 吨地磅,120 吨地磅厂家最新推荐,产能、专利、环保三维数据透视!
  • 精通CTS与低功耗时钟设计
  • GISDataMgr(数据管理工具)
  • 202510月年口碑好的板式家具品牌前十榜单推荐
  • 2025年板式家具品牌行业趋势与top5排名解析
  • 2025年10月口碑好的板式家具厂家前十名推荐
  • 学习笔记510—怎么去除”想要访问你的钥匙串中的密钥“Adobe Licensing ”若要给予许可
  • 蓝狐家庭维修小程序系统:一站式家庭维修服务解决方案
  • 打造智慧体育场馆的“视觉中枢”:国标GB28181算法算力平台EasyGBS助力体育中心实现全域感知与智能升级
  • 完整教程:【强化学习】#8 DQN(深度Q学习)
  • 达梦删除数据文件后恢复
  • 贪心训练
  • 漫格搭子交友系统:一站式同城社交解决方案
  • 多功能名片小程序系统:助力企业与个人高效拓展人脉