第一次作业

发布时间 2023-09-23 20:02:24作者: 李波102102157

作业1:

爬取大学排名实验

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

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

代码

import urllib.request
from bs4 import BeautifulSoup

def get_html(url):  #get_html(url) 函数用于发送GET请求并获取指定URL的HTML内容。
    response = urllib.request.urlopen(url) # 发送一个GET请求到指定的URL,并返回一个类文件对象
    return response.read() #类文件对象中读取所有的内容,并返回结果作为字符串。

def get_ur(html, top_n):  #函数是用于从给定的HTML内容中提取大学排名信息的函数。
    soup = BeautifulSoup(html, 'html.parser') #创建一个BeautifulSoup对象,用于解析HTML内容。

    table = soup.find('table', class_='rk-table')#通过调用find()方法,从解析后的HTML中找到class属性为'rk-table'的table元素。这个table包含了大学排名信息。
    rows = table.find_all('tr') #调用find_all()方法,从上一步找到的table元素中找到所有的tr元素。这些tr元素对应着每个大学的排名信息。

#这段代码是在循环中提取每个大学的排名信息,并将其添加到universities列表中。
    universities = []
    for row in rows[1:top_n+1]:
        cols = row.find_all('td')
        rank = cols[0].text.strip()
        name = cols[1].text.strip()
        location = cols[2].text.strip()
        type = cols[3].text.strip()
        score = cols[4].text.strip()

        universities.append({
            'rank': rank,
            'name': name,
            'location': location,
            'type': type,
            'score': score
        })

    return universities
#这段代码定义了一个名为 print_ur(universities) 的函数,用于打印大学排名信息。
def print_ur(universities):
    print("{:<5} {:<30} {:<10} {:<10} {:<10}".format(
        "排名", "学校名称", "省市", "学校类型", "总分"
    ))
    for uni in universities:
        print("{:<5} {:<30} {:<10} {:<10} {:<10}".format(
            uni['rank'], uni['name'], uni['location'], uni['type'], uni['score']
        ))

def main():
    url = 'http://www.shanghairanking.cn/rankings/bcur/2020'
    html = get_html(url)#调用 get_html() 函数,传入URL作为参数,用于获取指定URL的网页内容,并将结果赋值给 html 变量。
    top_n = int(input("请输入您的学号尾数最后两位:"))
    universities = get_ur(html, top_n)
    print_ur(universities)

if __name__ == '__main__':
    main()



心得体会
我主要通过以下几步完成该实验的:

  1. 导入所需的模块:urllib.request用于发送HTTP请求,BeautifulSoup用于解析HTML内容。
  2. 定义函数get_html(url):该函数用于发送GET请求,并返回指定URL的HTML内容。
  3. 定义函数get_ur(html, top_n):该函数用于从给定的HTML内容中提取大学排名信息。它使用BeautifulSoup库解析HTML内容,然后通过查找特定的HTML标签和类属性获取表格数据,最后将提取的大学排名信息封装成字典并添加到列表中。
  4. 定义函数print_ur(universities):该函数用于打印大学排名信息。它接收一个包含大学排名信息的列表作为参数,并按照一定的格式将排名信息输出到控制台。
  5. 定义主函数main():主要逻辑在这里实现。它首先指定要爬取的网页URL,然后调用get_html()函数获取网页内容。接着,根据用户输入的学号尾数最后两位调用get_ur()函数提取相应数量的大学排名信息,并将结果传递给print_university_rankings()函数进行打印。
  6. 执行主函数:通过if name == 'main':语句判断是否直接执行当前脚本,如果是,则调用main()函数,实现整个程序的执行。

作业2

爬取书包实验

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

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

代码

import re
import requests
from bs4 import BeautifulSoup

#使用requests库发送GET请求,传入商品页面的URL和请求头(header)。
def get_product_info(url):
    header = {
        'cookie': 'shshshfp=37788960d9de4f1694418d1f835e4193; shshshfpa=c9ceb152-a038-430e-8367-b112e1f095fe-1652947625; shshshfpx=c9ceb152-a038-430e-8367-b112e1f095fe-1652947625; __jdu=16891278724902068376087; areaId=16; PCSYCityID=CN_350000_350100_0; pinId=qAjpqS-u22Ko07zOSh6uE7V9-x-f3wj7; pin=jd_4e2d9f0fb0633; unick=jd_4e2d9f0fb0633; _tp=%2BZnLdk2Lbv6efJyKLv%2F0gSsklbED4QgiDIGKsyHAGnU%3D; _pst=jd_4e2d9f0fb0633; qrsc=3; ipLoc-djd=16-1317-1322-22758; unpl=JF8EALNnNSttURhQAEsKSBVFTlRTWw4MGB4KbTJRUA1dHAYCGAJIRRB7XlVdXxRKHx9sZxRUWVNLVQ4aBisSEXteU11bD00VB2xXXAQDGhUQR09SWEBJJVlQXl4ITxcFZ2A1ZF5Ye1QEKwIcGxhLXlJXWwtOHwJsZgJdX15MVQwdMhoiF3ttZF5VC0gTAF9mNVVtGh8IDR8BGREXBl1TV1UISBEKaWQAXFxbSlMMGQQcExlNbVVuXg; jsavif=0; jsavif=0; rkv=1.0; mba_muid=16891278724902068376087; TrackID=1Vzt6aYxDcHry_nMs0XzEm8Yz4XITfC6VgUIFl2mnQKqzDJjCC50avPOYdubD8mur1qbySoPXdh212GOSO0_pCNeth_InJJFlZRe1Fh7ncwzKtw2aLDo49EZ9Mm0ihQDS; thor=E8E7891E740C89411E5B398677FAD845D8D9D1025CFE8FF69EC033BA66A51BDCC9F90BBD6253AC4D117DC8CDE6AF8397509ACA807AF7FD360BA7247C84929042733545F84F67C9D5505F3A56A7A6E3F5715963089D16A1E76BEF043C22C9699E2E8E215579F9B6EF0493DBDFCEF9A88275ADA68159FC461080A4DD07E17FCB63110C27B83D475B7A175105F53FE07790A5864FA0F163A88E7F25FDB607F1EAD5; flash=2_mAUu-6b3GRy5_W6KdPvqcE_7IpZgqn38d4UwabqRWHbKUrxcj0Yt_aEjLTGlnqckthvYEzR8QEKrFNZ7gr-2mvR_ylGEdhDGifBvXy1beZK*; ceshi3.com=000; wlfstk_smdl=bnot383oa6gfdp5c9q5ahsxnv7rchebt; __jdv=76161171|haosou-search|t_262767352_haosousearch|cpc|5512151796_0_8b54a9b6d4864b5b883de5a4fc621bf1|1695280431913; __jda=122270672.16891278724902068376087.1689127872.1694939573.1695280206.3; __jdc=122270672; token=e7de5baf38b236d08c80a1a69e7a1725,3,941822; __tk=sUu5sLqBrf2nribiqAa5qUSCOiTiNiS5qUzerIGBrDvhNIbdqLa3Nu,3,941822; 3AB9D23F7A4B3CSS=jdd03X3F64P7LHHCDS55FEDWMPBICJ3QIOO23FIBNK2RLHT2ZX2EHECT622HGLSS3DGNECLSZV3ZRQKOOIMROQ5ZVLT3JEQAAAAMKW2MOOCQAAAAAD33WITFTHZTN5MX; xapieid=jdd03X3F64P7LHHCDS55FEDWMPBICJ3QIOO23FIBNK2RLHT2ZX2EHECT622HGLSS3DGNECLSZV3ZRQKOOIMROQ5ZVLT3JEQAAAAMKW2MOOCQAAAAAD33WITFTHZTN5MX; 3AB9D23F7A4B3C9B=X3F64P7LHHCDS55FEDWMPBICJ3QIOO23FIBNK2RLHT2ZX2EHECT622HGLSS3DGNECLSZV3ZRQKOOIMROQ5ZVLT3JEQ; shshshsID=a6c79611eb5df96736ca4d9a7eaa3d67_10_1695280697979; __jdb=122270672.13.16891278724902068376087|3.1695280206; shshshfpb=AAgWSmraKEs6xUqA4Qw6DZ7ES4fCV_hZSlHYlUAAAAAA',
        'referer': 'https://www.jd.com/',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42',
    }

    r = requests.get(url, headers=header)
#通过BeautifulSoup库解析返回的HTML文档。
    soup = BeautifulSoup(r.text, "html.parser")
#使用find_all()方法找到商品名称和价格所在的HTML标签,获取对应的文本内容。
    ptl = soup.find_all('div', 'p-price')
    tlt = soup.find_all('div', 'p-name p-name-type-2')
#将商品名称和价格存储在一个字典中,并将字典添加到列表中保存。
    products = []
#循环遍历列表,输出商品名称和价格。
    for i in range(len(tlt)):
        title = tlt[i].find('em').text
        price = ""
        if len(ptl) > 0:
            price_tag = ptl[i].strong.i
            if price_tag:
                price = price_tag.text.strip()
        products.append({"商品名称": title, "商品价格": price})

    return products


# 测试函数
url = 'https://search.jd.com/Search?keyword=%E4%B9%A6%E5%8C%85&enc=utf-8&wq=%E4%B9%A6%E5%8C%85&pvid=97148abdff094172b6753c116da7b2ca'
product_info = get_product_info(url)
for product in product_info:
    print(f"商品名称:{product['商品名称']}")
    print(f"商品价格:{product['商品价格']}")


心得体会

  1. 使用requests库发送GET请求,传入商品页面的URL和请求头(header)。
  2. 通过BeautifulSoup库解析返回的HTML文档。
  3. 使用find_all()方法找到商品名称和价格所在的HTML标签,获取对应的文本内容。
  4. 将商品名称和价格存储在一个字典中,并将字典添加到列表中保存。
  5. 循环遍历列表,输出商品名称和价格。

作业3

给定网页爬取图片实验

要求:爬取一个给定网页( https://xcb.fzu.edu.cn/info/1071/4481.htm)或者自选网页的所有JPEG和JPG格式文件
输出信息:将自选网页内的所有JPEG和JPG文件保存在一个文件夹中
代码

import requests
from bs4 import BeautifulSoup
import os
import uuid
import threading
from queue import Queue
from urllib.parse import urljoin

# 设置图片保存路径和爬取线程数
save_folder = 'images'
num_threads = 8

# 定义图片下载函数
def download_image(url):
    try:
        res = requests.get(url, timeout=10)
        res.raise_for_status()
        image_data = res.content

        # 生成随机的文件名
        filename = str(uuid.uuid4()) + os.path.splitext(url)[-1]

        # 保存图片
        with open(os.path.join(save_folder, filename), 'wb') as f:
            f.write(image_data)

        print('图片下载成功:', url)
    except Exception as e:
        print('图片下载失败:', url, str(e))

# 定义多线程爬取函数
def crawl_images(url_list, thread_num):
    # 创建任务队列
    task_queue = Queue()

    # 将URL添加到任务队列中
    for url in url_list:
        task_queue.put(url)

    # 定义工作函数
    def worker():
        while True:
            try:
                # 从任务队列中获取任务
                url = task_queue.get(block=False)
            except Exception as e:
                break

            # 执行任务
            download_image(url)

            # 标记任务已完成
            task_queue.task_done()

    # 启动多个线程
    threads = []
    for i in range(thread_num):
        t = threading.Thread(target=worker)
        t.start()
        threads.append(t)

    # 等待所有线程完成
    for t in threads:
        t.join()

    # 判断是否所有任务都已完成
    if task_queue.empty():
        print('所有图片下载完成!')
    else:
        print('部分图片下载失败,请重试。')

# 定义主函数
def main():
    try:
        # 发送HTTP请求获取网页内容
        url = 'https://xcb.fzu.edu.cn/info/1071/4481.htm'
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        html = response.text

        # 创建保存图片的文件夹
        if not os.path.exists(save_folder):
            os.makedirs(save_folder)

        # 使用BeautifulSoup解析网页内容
        soup = BeautifulSoup(html, 'html.parser')

        # 提取所有的图片链接
        image_links = soup.find_all('img')

        # 构造图片的完整URL,并添加到列表中
        urls = []
        for image_link in image_links:
            src = image_link.get('src')
            if src and (src.endswith('.jpeg') or src.endswith('.jpg')):
                full_url = urljoin(url, src)
                urls.append(full_url)

        # 使用多线程进行图片下载
        crawl_images(urls, num_threads)
    except Exception as e:
        print('爬取过程出现错误:', str(e))

if __name__ == '__main__':
    main()




心得体会

  1. 导入所需的模块:requests用于发送HTTP请求,BeautifulSoup用于解析HTML内容,os用于操作文件系统,uuid用于生成唯一的文件名,threading用于实现多线程,Queue用于创建任务队列,urljoin用于构造完整的URL。
  2. 设置图片保存路径和爬取线程数:通过设置save_folder变量指定图片保存路径,设置num_threads变量指定爬取线程数。
  3. 定义图片下载函数download_image(url):该函数用于下载指定URL的图片。它发送HTTP请求获取图片内容,生成一个随机的文件名,然后将图片数据保存到指定路径下。
  4. 定义多线程爬取函数crawl_images(url_list, thread_num):该函数用于多线程爬取图片。它首先创建一个任务队列task_queue,将所有待下载的URL添加到队列中。然后定义了一个工作函数worker(),不断从任务队列中获取任务并执行下载图片的操作,直到队列为空。之后启动多个线程去执行工作函数,并等待所有线程完成任务。
  5. 定义主函数main():主要逻辑在这里实现。首先发送HTTP请求获取网页内容,然后创建保存图片的文件夹。接着使用BeautifulSoup解析网页内容,提取所有的图片链接。构造完整的图片URL,并将其添加到列表中。最后调用crawl_images()函数使用多线程进行图片下载。
  6. 执行主函数:通过if name == 'main':语句判断是否直接执行当前脚本,如果是,则调用main()函数,实现整个程序的执行。