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

数据采集第3次作业

作业1

图片2种方式爬取实验

(1)要求:要求:指定一个网站,爬取这个网站中的所有的所有图片,例如中国气象网(http://www.weather.com.cn)。实现单线程和多线程的方式爬取。

代码:

单线程

# simple_single.py
import os
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoupurl = 'http://www.weather.com.cn' # 要爬取的网页地址
headers = {'User-Agent': 'Mozilla/5.0'} # 模拟浏览器
os.makedirs('weather_images_single', exist_ok=True)# 获取页面并解析图片链接
resp = requests.get(url, headers=headers) # 向目标网站发送 GET 请求
soup = BeautifulSoup(resp.text, 'html.parser') # 使用 BeautifulSoup 解析返回的 HTML 文本
img_urls = [urljoin(url, img['src']) for img in soup.find_all('img', src=True)] # 提取所有 <img> 标签中带有 src 属性的元素,并将 src 值转为绝对 URL# 去除重复的URL
img_urls = list(set(img_urls))# 打印所有图片 URL
print(f"共找到 {len(img_urls)} 张图片:")
# 遍历图片 URL 列表,按序号逐行打印
for i, u in enumerate(img_urls, 1):print(f"{i}. {u}")# 逐个下载
for u in img_urls:try:r = requests.get(u, headers=headers) # 向图片 URL 发起请求# 只有状态码为 200(成功)时才保存if r.status_code == 200:filename = u.split('/')[-1].split('?')[0] or 'image.jpg'with open(f'weather_images_single/{filename}', 'wb') as f:f.write(r.content)   # 以二进制写模式打开文件,保存图片内容except:pass
print(" 单线程下载完成!")

多线程

# simple_multi.py
import os
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutorurl = 'http://www.weather.com.cn' # 要爬取的网页地址
headers = {'User-Agent': 'Mozilla/5.0'} # 模拟浏览器
os.makedirs('images_mt', exist_ok=True)# 获取图片链接
resp = requests.get(url, headers=headers)  # 向目标网站发送 GET 请求
soup = BeautifulSoup(resp.text, 'html.parser') # 使用 BeautifulSoup 解析返回的 HTML 文本
img_urls = [urljoin(url, img['src']) for img in soup.find_all('img', src=True)] # 提取所有 <img> 标签中带有 src 属性的元素,并将 src 值转为绝对 URL# 去除重复的URL
img_urls = list(set(img_urls))# 打印
print(f"共找到 {len(img_urls)} 张图片:")
# 遍历图片 URL 列表,按序号逐行打印
for i, u in enumerate(img_urls, 1):print(f"{i}. {u}")# 下载函数
def download(u):try:r = requests.get(u, headers=headers) # 向图片 URL 发起请求# 只有状态码为 200(成功)时才保存if r.status_code == 200:filename = u.split('/')[-1].split('?')[0] or 'image.jpg'with open(f'images_mt/{filename}', 'wb') as f:f.write(r.content)   # 以二进制写模式打开文件,保存图片内容except:pass# 并发下载
with ThreadPoolExecutor(5) as pool:pool.map(download, img_urls)print(" 多线程下载完成!")

结果:

image
image
image
image

(2)心得体会:

通过实现单线程与多线程爬取中国气象网图片,我深刻体会到多线程在I/O密集型任务中的显著效率优势。单线程逻辑简单、易于调试,但速度慢;多线程虽需处理并发控制和异常管理,却能大幅提升爬取速度。同时,遵守网站robots协议、设置合理请求间隔,是负责任网络爬虫的基本素养。

作业2

Scrapy+Xpath股票爬取实验

(1)要求:熟练掌握 Scrapy 中 Item、Pipeline 数据的序列化输出方法;使用 Scrapy + XPath + MySQL 数据库存储技术路线爬取股票相关信息。

核心代码:

class EastmoneyStockSpider(scrapy.Spider):name = 'eastmoney_stock'def start_requests(self):# 构造东方财富网股票行情 API 的完整 URLurl = ("https://28.push2.eastmoney.com/api/qt/clist/get?""pn=1&pz=100&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&""fltt=2&invt=2&fid=f3&""fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&""fields=f12,f14,f2,f3,f4,f5,f6,f15,f16,f17,f18")# 设置请求头(Headers),模拟浏览器访问,避免被反爬headers = {'Referer': 'https://quote.eastmoney.com/','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36',}# 使用 yield 返回 Request 对象yield scrapy.Request(url=url, headers=headers, callback=self.parse)def parse(self, response):try:# 将响应体(response.text)解析为 Python 字典data = json.loads(response.text)# 从 JSON 中提取股票列表stocks = data.get('data', {}).get('diff', [])now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")  # 当前时间# 遍历每一只股票for stock in stocks:item = StockItem()# 从 JSON 字段中提取对应值,并赋给 Item 的各个字段item['股票代码'] = stock.get('f12', '')item['股票名称'] = stock.get('f14', '')item['当前价格'] = str(stock.get('f2', ''))item['涨跌幅百分比'] = str(stock.get('f3', ''))      item['涨跌额'] = str(stock.get('f4', ''))item['成交量手'] = str(stock.get('f5', ''))item['成交额元'] = str(stock.get('f6', ''))item['振幅百分比'] = str(stock.get('f17', ''))item['最高价'] = str(stock.get('f15', ''))item['最低价'] = str(stock.get('f16', ''))item['开盘价'] = str(stock.get('f18', ''))          item['昨收价'] = str(stock.get('f3', ''))item['更新时间'] = now           yield item   # 将填充好的 Item 交给 Scrapy 引擎except Exception as e:self.logger.error(f"解析失败: {e}")
# stock_spider/items.py
import scrapyclass StockItem(scrapy.Item):股票代码 = scrapy.Field()股票名称 = scrapy.Field()当前价格 = scrapy.Field()涨跌幅百分比 = scrapy.Field()   涨跌额 = scrapy.Field()成交量手 = scrapy.Field()成交额元 = scrapy.Field()振幅百分比 = scrapy.Field()     最高价 = scrapy.Field()最低价 = scrapy.Field()开盘价 = scrapy.Field()昨收价 = scrapy.Field()更新时间 = scrapy.Field()
# stock_spider/pipelines.py
import sqlite3class StockPipeline:def open_spider(self, spider):self.conn = sqlite3.connect('stocks.db')self.cursor = self.conn.cursor()self.cursor.execute('''CREATE TABLE IF NOT EXISTS stocks (id INTEGER PRIMARY KEY AUTOINCREMENT,股票代码 TEXT UNIQUE,股票名称 TEXT,当前价格 TEXT,涨跌幅百分比 TEXT,涨跌额 TEXT,成交量手 TEXT,成交额元 TEXT,振幅百分比 TEXT,最高价 TEXT,最低价 TEXT,开盘价 TEXT,昨收价 TEXT,更新时间 TEXT)''')self.conn.commit()def process_item(self, item, spider):self.cursor.execute('''INSERT OR REPLACE INTO stocks (股票代码, 股票名称, 当前价格, 涨跌幅百分比, 涨跌额,成交量手, 成交额元, 振幅百分比, 最高价, 最低价, 开盘价, 昨收价, 更新时间)VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', (item['股票代码'],item['股票名称'],item['当前价格'],item['涨跌幅百分比'],item['涨跌额'],item['成交量手'],item['成交额元'],item['振幅百分比'],item['最高价'],item['最低价'],item.get('开盘价', ''),      item.get('昨收价', ''),item.get('更新时间', '')))self.conn.commit()return item  def close_spider(self, spider):self.conn.close()
# stock_spider/settings.pyBOT_NAME = 'stock_spider'
SPIDER_MODULES = ['stock_spider.spiders']
NEWSPIDER_MODULE = 'stock_spider.spiders'ROBOTSTXT_OBEY = False
CONCURRENT_REQUESTS = 1
DOWNLOAD_DELAY = 2
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36'ITEM_PIPELINES = {'stock_spider.pipelines.StockPipeline': 300,
}LOG_LEVEL = 'WARNING'
# 控制 CSV 字段顺序和编码FEED_EXPORT_ENCODING = 'utf-8-sig'  # 防止 Excel 乱码(带 BOM 的 UTF-8)
FEED_EXPORT_FIELDS = ['股票代码','股票名称','当前价格','涨跌幅百分比','涨跌额','成交量手','成交额元','振幅百分比','最高价','最低价','开盘价','昨收价','更新时间'
]

结果:

屏幕截图 2025-11-18 165517

(2)心得体会:

通过本次实践,我深入掌握了Scrapy框架中Item定义与Pipeline数据处理的流程,熟练运用XPath精准提取股票信息,并成功将数据持久化至MySQL数据库。整个过程强化了我对网络爬虫结构化设计的理解,也提升了数据清洗、字段映射及异常处理能力,为后续复杂爬虫项目打下坚实基础。

作业3

Scrapy+Xpath爬取外汇信息实验

(1)要求:熟练掌握 Scrapy 中 Item、Pipeline 数据的序列化输出方法;使用 Scrapy 框架 + XPath + MySQL 数据库存储技术路线爬取外汇网站数据。

核心代码:

# boc_spider/spiders/boc.py
import scrapy
from boc_spider.items import BocItemclass BocSpider(scrapy.Spider):name = 'boc'allowed_domains = ['boc.cn']start_urls = ['https://www.boc.cn/sourcedb/whpj/']def parse(self, response):# 选择页面中第二个 table(第一个是顶部导航)tables = response.xpath('//table')if len(tables) < 2:self.logger.error("未找到数据表格")returndata_table = tables[1]  # 第二个 table# 获取所有行rows = data_table.xpath('.//tr')# 跳过第一行(表头)for row in rows[1:]:tds = row.xpath('./td/text()').getall()if len(tds) < 7:continueitem = BocItem()item['Currency'] = tds[0].strip()item['TBP'] = tds[1].strip()      # 现汇买入价item['CBP'] = tds[2].strip()      # 现钞买入价item['TSP'] = tds[3].strip()      # 现汇卖出价item['CSP'] = tds[4].strip()      # 现钞卖出价item['Time'] = tds[6].strip()     # 发布日期yield item
# boc_spider/items.py
import scrapyclass BocItem(scrapy.Item):Currency = scrapy.Field()TBP = scrapy.Field()CBP = scrapy.Field()TSP = scrapy.Field()CSP = scrapy.Field()Time = scrapy.Field()
# boc_spider/pipelines.py
import sqlite3class BocPipeline:def open_spider(self, spider):self.conn = sqlite3.connect('boc_exchange.db')self.cursor = self.conn.cursor()self.cursor.execute('''CREATE TABLE IF NOT EXISTS exchange_rates (id INTEGER PRIMARY KEY AUTOINCREMENT,Currency TEXT,TBP TEXT,CBP TEXT,TSP TEXT,CSP TEXT,Time TEXT)''')self.conn.commit()def process_item(self, item, spider):self.cursor.execute('''INSERT OR REPLACE INTO exchange_rates (Currency, TBP, CBP, TSP, CSP, Time)VALUES (?, ?, ?, ?, ?, ?)''', (item['Currency'], # 从 Item 中提取货币名称item['TBP'],      # 现汇买入价item['CBP'],      # 现钞买入价item['TSP'],      # 现汇卖出价item['CSP'],      # 现钞卖出价item['Time']      # 更新时间))self.conn.commit()return itemdef close_spider(self, spider):self.conn.close()
# boc_spider/settings.py
BOT_NAME = 'boc_spider'SPIDER_MODULES = ['boc_spider.spiders']
NEWSPIDER_MODULE = 'boc_spider.spiders'ROBOTSTXT_OBEY = False
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36'
# 启用 SQLITE3
ITEM_PIPELINES = {'boc_spider.pipelines.BocPipeline': 300,
}
CONCURRENT_REQUESTS_PER_DOMAIN = 1
DOWNLOAD_DELAY = 1FEED_EXPORT_ENCODING = 'utf-8'
ADDONS = {}
# 控制 CSV 字段顺序和编码(防 Excel 乱码)
FEED_EXPORT_ENCODING = 'utf-8-sig'
FEED_EXPORT_FIELDS = ['Currency', 'TBP', 'CBP', 'TSP', 'CSP', 'Time']

结果:

屏幕截图 2025-11-18 165758

(2)心得体会:

通过本次爬取外汇数据的实践,我进一步掌握了Scrapy框架中Item和Pipeline的使用,能够熟练结合XPath提取目标字段,并将结构化数据高效存储到MySQL数据库。整个过程加深了我对爬虫数据流转机制的理解,也提升了在实际项目中处理动态网页与数据持久化的综合能力。

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

相关文章:

  • php openssl, RSA私钥有PKCS#1和PKCS#8,均包含有公钥
  • 2025 年 11 月中空吹塑机厂家推荐排行榜,吹塑机,挤出吹塑机,注射吹塑机,拉伸吹塑机,发泡吹塑机,工具箱吹塑机,瓶子吹塑机公司推荐
  • CF359D-Pair of Numbers
  • 2025.11.18 写题记录
  • F032 材料科学文献知识图谱可视化分析架构(四种知识图谱可视化布局) | vue + flask + echarts + d3.js 建立
  • 2025年AI IDE的深度评测与推荐:从单一功能效率转向生态壁垒 - 教程
  • 2025年AI IDE的深度评测与推荐:从单一功能效率转向生态壁垒 - 教程
  • 2025 最新支架厂家排行榜,出口级品质 + 定制服务 工程采购优选推荐电缆沟/弧形电缆沟/隧道电缆/管廊电力/角钢电缆/热镀锌角钢电缆沟支架厂家
  • vue3 波纹效果
  • 2025 最新支架厂家排行榜,出口级品质 + 定制服务 工程采购优选推荐指南热浸锌电缆/可调节角度隧道电缆沟/定制电缆沟/热镀锌电缆沟支架公司推荐
  • gvim linux
  • JDK21升级
  • gun linux
  • 2025年上海泰迪熊狗护理渠道权威推荐榜单:约克夏狗/西高地幼犬/可卡布犬用品及宠物店服务供应商精选
  • 渲染相关(Markdown、ByteMD、ReactMarkdown) - 实践
  • 2025 最新套袋机厂家权威推荐榜:聚焦技术创新与专利优势,涵盖多类型设备优质品牌汇总自动套袋机/全自动套袋机/侧推式套袋机/卧式套袋机厂家推荐
  • 正宗粮食酒一箱6瓶哪个品牌好?2025品牌精选:品质与性价比的考量
  • 2025 最新推荐装盒机厂家权威排行榜:全自动 / 食品 / 纸巾 / 卫生巾装盒机技术创新与整线配套能力测评报告
  • NCHU_单部电梯调度程序大作业
  • 2025-11-22
  • 2025年好吃不贵的餐厅服务权威推荐榜单:宝藏餐厅/好吃的餐厅/口碑好的餐厅服务精选
  • 2025年郑州婚姻心理咨询公司权威推荐榜单:心理健康咨询/家庭心理咨询/心理咨询源头公司精选
  • grub命令行启动linux
  • gtk的linux
  • gui linux
  • 2025 年 11 月音响分频器,汽车音响分频器,喇叭分频器厂家最新推荐,产能、专利、环保三维数据透视!
  • 2025 年 11 月方形冷却塔,圆形冷却塔,横流冷却塔,逆流冷却塔厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!
  • 2025 最新分频器厂家权威排行榜:EMF 三维电感技术加持,国际协会认证品质之选音响分频器/汽车音响分频器/喇叭分频器公司推荐
  • vue前端面试题——记录一次面试当中遇到的题(10) - 详解
  • Grid-dp,交互