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

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

🔗1.相关信息及链接

名称 信息及链接
学号姓名 102202108 王露洁
本次作业要求链接 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/homework/13286
作业①所在码云链接 https://gitee.com/wanglujieeee/crawl_project/tree/master/作业1.1
作业②所在码云链接 https://gitee.com/wanglujieeee/crawl_project/tree/master/作业1.2
作业③所在码云链接 https://gitee.com/wanglujieeee/crawl_project/tree/master/作业1.3

📚2.作业内容

作业①:

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

🔋输出信息:

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

💡代码实现(详细注释版)

import requests  # 导入requests库,用于发送HTTP请求  
from bs4 import BeautifulSoup  # 导入BeautifulSoup库,用于解析HTML文档  
import pandas as pd  # 导入pandas库,用于数据处理和生成DataFrame  
  
# 目标URL,即我们要抓取的网页地址  
url = "http://www.shanghairanking.cn/rankings/bcur/2020"  
  
try:  
    # 发送HTTP GET请求到目标URL  
    resp = requests.get(url)  
    # 检查请求是否成功,如果失败则抛出HTTPError异常  
    resp.raise_for_status()  
      
    # 获取网页的HTML内容  
    html = resp.content  
      
    # 使用BeautifulSoup解析HTML文档,'lxml'是解析器  
    soup = BeautifulSoup(html, 'lxml')  
      
    # 查找网页中的排名表格,这里假设表格的<table>标签是唯一的,实际情况可能需要根据HTML结构修改选择器  
    ranking_table = soup.find('table')  
      
    # 如果找到了排名表格  
    if ranking_table:  
        # 查找表格中的所有行<tr>  
        rows = ranking_table.find_all('tr')  
        # 初始化一个空列表,用于存储每行的数据  
        list_of_rows = []  
          
        # 遍历每一行  
        for row in rows:  
            # 查找行中的所有单元格<td>(这里排除了<th>,因为表格头部通常不包含我们需要的数据)  
            cells = row.find_all(['td'])  
            # 初始化一个空列表,用于存储当前行的数据  
            row_data = []  
              
            # 遍历当前行的每个单元格  
            for i, cell in enumerate(cells, start=1):  
                # 如果当前单元格是第二列(即学校中文名称),则特殊处理  
                if i == 2:  
                    # 在单元格中查找class为"name-cn"的元素,这通常是学校中文名称的容器  
                    cell = cell.find(class_="name-cn")  
                    # 如果找到了,则将其文本内容(去除前后空白)添加到行数据中  
                    if cell:  
                        row_data.append(cell.text.strip())  
                # 如果当前单元格是第六列(我们不需要的列,比如操作按钮等),则停止继续处理当前行的剩余单元格  
                elif i == 6:  
                    break  
                # 对于其他单元格,直接将其文本内容(去除前后空白)添加到行数据中  
                else:  
                    row_data.append(cell.text.strip())  
              
            # 如果当前行有数据(即非空行),则将其添加到列表中  
            if row_data:  
                list_of_rows.append(row_data)  
          
        # 使用pandas库将列表转换为DataFrame,并指定列名  
        df = pd.DataFrame(list_of_rows, columns=['排名', '学校名称', '省市', '学校类型', '总分'])  
        # 打印DataFrame  
        print(df)  
    else:  
        # 如果没有找到排名表格,则打印提示信息  
        print('未找到排名表格。')  
except requests.exceptions.RequestException as e:  
    # 捕获requests库抛出的异常,并打印错误信息  
    print(f'无法打开网址:{url},错误:{e}')  
except Exception as e:  
    # 捕获其他所有异常,并打印错误信息  
    print(f'发生错误:{e}')

🌻运行结果截图

💌心得体会

在深入学习和实践这段代码后,我深刻感受到编程的魅力与挑战并存。代码不仅仅是实现功能的工具,更是一种严谨的逻辑思考和问题解决能力的体现。通过不断调试和优化,我学会了如何更有效地利用requests和BeautifulSoup库来抓取和解析网页数据,同时也掌握了使用pandas处理和分析数据的基本技巧。这个过程不仅锻炼了我的技术实力,更让我明白,编程需要细心、耐心和不断的学习。每一次成功抓取到数据,都让我对编程有了更深的理解和热爱。

作业②:

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

🔋输出信息:

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

💡代码实现

# 导入必要的库  
from bs4 import BeautifulSoup  # 用于解析HTML文档  
from bs4.dammit import UnicodeDammit  # 用于处理字符编码问题  
import requests  # 用于发送HTTP请求  
import pandas as pd  # 用于数据处理和生成DataFrame  
  
# 目标URL,即我们要抓取的当当网搜索页面地址(已进行URL编码)  
url = "http://search.dangdang.com/?key=%CA%E9%B0%FC&act=input"  
  
try:  
    # 设置HTTP请求头,模拟浏览器访问,避免被网站反爬虫机制识别为爬虫  
    headers = {  
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"  
    }  
  
    # 发送HTTP GET请求到目标URL,并带上请求头  
    data = requests.get(url, headers=headers)  
  
    # 检查请求是否成功,如果失败则抛出HTTPError异常  
    data.raise_for_status()  
  
    # 获取网页的原始内容(字节码)  
    raw_content = data.content  
  
    # 使用UnicodeDammit处理字符编码问题,尝试使用utf-8和gbk编码,选择最合适的编码方式  
    dammit = UnicodeDammit(raw_content, ["utf-8", "gbk"])  
  
    # 获取处理后的Unicode字符串(即HTML文档)  
    html_content = dammit.unicode_markup  
  
    # 使用BeautifulSoup解析HTML文档,'lxml'是解析器  
    soup = BeautifulSoup(html_content, "lxml")  
  
    # 使用CSS选择器查找所有匹配的<li>元素,这些元素位于class为'bigimg'的<ul>下  
    # 注意:这里的选择器需要根据网页的实际结构进行调整  
    lis = soup.select("ul.bigimg li")  
  
    # 初始化一个空列表,用于存储每个商品的数据  
    products_data = []  
  
    # 遍历每个<li>元素(即每个商品)  
    for li in lis:  
        try:  
            # 初始化一个空列表,用于存储当前商品的数据  
            current_product_data = []  
  
            # 使用CSS选择器查找商品名称的<a>标签,并获取其title属性(商品名称)  
            # 注意:如果<a>标签不存在或没有title属性,将返回空字符串  
            name_tag = li.select_one("p.name a")  
            name = name_tag.get('title', '') if name_tag else ''  
  
            # 使用CSS选择器查找商品价格,并获取其文本内容(去除前后空白)  
            # 注意:如果价格标签不存在,将返回空字符串  
            price_tag = li.select_one("span.price_n")  
            price = price_tag.text.strip() if price_tag else ''  
  
            # 将商品名称和价格添加到当前商品的数据列表中  
            current_product_data.append(name)  
            current_product_data.append(price)  
  
            # 将当前商品的数据列表添加到总列表中  
            products_data.append(current_product_data)  
        except Exception as err:  
            # 如果在处理某个商品时发生异常,则打印错误信息,并继续处理下一个商品  
            print(f"Error processing item: {err}")  
  
    # 使用pandas库将总列表转换为DataFrame,并指定列名  
    df = pd.DataFrame(products_data, columns=['商品名称', '价格'])  
  
    # 调整DataFrame中列的顺序,将'价格'列放在前面,'商品名称'列放在后面  
    df = df[['价格', '商品名称']]  
  
    # 打印DataFrame,查看抓取到的商品数据  
    print(df)  
except Exception as err:  
    # 如果在请求网页或处理数据时发生异常,则打印错误信息  
    print(f"An error occurred: {err}")

🌻运行结果截图(部分)

💌心得体会

在编写和调试上述代码的过程中,我深刻体会到了几个关键点。首先,数据的抓取和解析需要耐心和细致,因为网页的结构往往复杂多变,选择器必须精确无误。其次,编码问题在实际开发中是一个常见的陷阱,使用UnicodeDammit这样的工具能够大大简化这一过程。再者,异常处理对于确保程序的健壮性至关重要,它可以帮助我们捕捉并处理潜在的错误,避免程序崩溃。最后,Pandas库在处理表格数据时表现出色,其强大的功能使得数据整理和分析变得更加简单高效。这次经历不仅提升了我的编程技能,也让我对Web开发和数据处理有了更深入的理解。

作业③:

🔌要求:爬取一个给定网页([https://news.fzu.edu.cn/yxfd.htm]))或者自选网页的所有JPEG和JPG格式文件,并将这些文件保存在一个指定的文件夹中。

🔋输出信息:将自选网页内的所有JPEG和JPG文件保存在一个文件夹中,文件夹中包含所有下载的图片文件。

💡代码实现

自选网页:https://search.dangdang.com/?key=Ӣ������&act=input&show=big&show_shop=0#J_tab

注意:查看过后发现该网页只有jps格式的图片,所以代码中体现的是只爬取了jps格式的图片

import requests  # 导入requests库,用于发送HTTP请求  
import re  # 导入re库,用于正则表达式匹配  
import os  # 导入os库,用于文件和目录操作  
  
# 定义当当网搜索页面的基础URL(已进行URL编码)  
base_url = f"https://search.dangdang.com/?key=%D3%A2%D3%EF%C2%FE%BB%AD&act=input&show=big&show_shop=0#J_tab"  
  
# 设置HTTP请求头,模拟浏览器访问,避免被网站反爬虫机制识别为爬虫  
headers = {"User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072421 Minefield/3.0.2pre"}  
  
# 检查是否存在名为"images"的目录,如果不存在则创建该目录  
if not os.path.exists("images"):  
    os.makedirs("images")  
  
def fetch_images(url):  
    """  
    发送HTTP GET请求到指定URL,并返回响应的HTML内容。  
    如果请求失败,则打印错误信息并返回None。  
    """  
    resp = requests.get(url, headers=headers)  
    if resp.status_code == 200:  
        return resp.text  
    else:  
        print(f"Failed to fetch page: {url}")  
        return None  
  
def parse_images(html):  
    """  
    使用正则表达式从HTML内容中提取图片URL。  
    匹配以'src='或'data-original='开头,并以'.jpg'结尾的URL。  
    返回提取到的图片URL列表。  
    """  
    # 注意:这里的正则表达式可能需要根据网页的实际结构进行调整  
    image_tuples = re.findall(r'(src|data-original)=["\'](//.*?\.jpg)["\']', html)  # 匹配以//开头的URL  
    image_urls = [img[1] for img in image_tuples]  
    return image_urls  
  
def save_images(image_urls):  
    """  
    遍历图片URL列表,下载图片并保存到本地"images"目录中。  
    图片文件名以"image_序号.jpg"的格式命名。  
    如果下载过程中发生异常,则打印错误信息。  
    """  
    for idx, img_url in enumerate(image_urls):  
        # 如果URL以//开头,则补充为完整的http或https URL(这里默认使用http)  
        if img_url.startswith('//'):  
            img_url = 'http:' + img_url  
  
        try:  
            # 发送HTTP GET请求到图片URL,并设置stream=True以流式方式下载图片  
            img_response = requests.get(img_url, stream=True)  
            img_response.raise_for_status()  # 确保请求成功  
  
            # 构造图片文件名  
            img_name = os.path.join("images", f"image_{idx + 1}.jpg")  
  
            # 以二进制写入方式打开文件,并将图片内容写入文件  
            with open(img_name, "wb") as img_file:  
                img_file.write(img_response.content)  
            print(f"Saved: {img_name}")  
        except Exception as e:  
            # 如果下载过程中发生异常,则打印错误信息  
            print(f"Could not save image {img_url}: {e}")  
  
def main():  
    """  
    主函数,用于执行整个图片抓取流程。  
    1. 从当当网搜索页面抓取HTML内容。  
    2. 解析HTML内容,提取图片URL。  
    3. 下载并保存前20张图片到本地。  
    """  
    html_content = fetch_images(base_url)  
    if html_content:  
        image_urls = parse_images(html_content)  
        # 限制只爬取前20个图片(注意:原代码中写的是[:20],但注释写的是前100个,这里以代码为准)  
        save_images(image_urls[:20])  
  
if __name__ == "__main__":  
    # 当脚本被直接运行时,调用main函数  
    main()

🌻运行结果截图


💌心得体会

通过编写这段代码,我掌握了如何使用Python进行网页内容抓取、解析以及图片下载的基本流程。首先,我学习了如何利用requests库模拟HTTP请求,并设置合适的请求头以绕过一些简单的反爬虫机制。其次,我了解到re模块在文本处理中的强大功能,通过正则表达式可以高效地提取出所需的信息,如图片URL。此外,我还学会了使用os模块进行文件操作,如创建目录和保存文件。在下载图片时,我意识到需要处理各种可能的异常情况,如网络请求失败或文件写入错误,这促使我更加深入地理解了异常处理的重要性。最后,通过限制爬取的图片数量,我学会了如何在抓取数据时保持礼貌,避免对目标网站造成过大的负担。这次实践不仅增强了我的编程技能,也让我对Web数据抓取有了更深入的理解。

posted @ 2024-10-16 13:14  bushiwanglujie  阅读(26)  评论(0编辑  收藏  举报