Live2D

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

作业①

1)实验

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

  • 输出信息:

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

2.代码

  • 导入所需的库:requests用于发送HTTP请求,BeautifulSoup用于解析HTML文档,bs4是BeautifulSoup的别名,PrettyTable用于制作表格。

  • 定义函数get_dangdang_WebContent(url),该函数接收一个URL参数,发送HTTP GET请求获取网页内容,并返回获取到的内容。
    通过开发者工具我们可以得到网页结构,知道我们所要的信息都在tr标签下的a、td标签里:

  • 定义函数extractList(clist, html),该函数接收两个参数,一个是存储数据的列表clist,另一个是要解析的HTML文档html。函数使用BeautifulSoup解析HTML文档,
    通过遍历找到排行榜数据所在的表格行,并将学校排行榜数据添加到clist列表中。

  • 定义函数printList(clist1, num),该函数接收两个参数,一个是存储数据的列表clist1,另一个是要打印的数据数量num。函数使用PrettyTable创建一个表格对象,
    设置表格的列名,然后逐一将每条学校排行榜数据添加到表格中,并最后打印格式化后的表格。

  • 定义主函数main(),在该函数中进行以下操作:

    • 创建一个空列表cinfo,用于存储学校排行榜数据
    • url=https://www.shanghairanking.cn/rankings/bcur/2020
    • 调用get_dangdang_WebContent()函数,获取网页内容,并将内容存储在html变量中
    • 调用extractList()函数,提取学校排行榜数据,并将数据存储在cinfo列表中
    • 调用printList()函数,打印前3条学校排行榜数据
  • 调用主函数main()

完整代码如下:

import requests
from bs4 import BeautifulSoup
import bs4
from prettytable import PrettyTable # 导入PrettyTable库,用于制作表格

def get_dangdang_WebContent(url):
    try:
        response = requests.get(url) # 发送HTTP GET请求获取网页内容
        data = response.content
        return data
    except Exception as err:
        print(err)

# 将html页面放到clist列表中
def extractList(clist, html):
    soup = BeautifulSoup(html, "html.parser") # 使用BeautifulSoup解析HTML文档
    for tr in soup.find('tbody').children: # 遍历排行榜数据所在的表格行
        if isinstance(tr, bs4.element.Tag): # 判断是否为Tag对象
            a = tr('a') # 获取学校名称所在的<a>标签
            tds = tr('td') # 获取当前行的所有<td>标签
            clist.append([tds[0].text.strip(), a[0].string.strip(), tds[2].text.strip(),
                          tds[3].text.strip(), tds[4].text.strip()]) # 将学校排行榜数据添加到clist列表中

def printList(clist1, num):
    x = PrettyTable() # 创建表格对象
    x.field_names = ["排名", "学校名称", "省份", "学校类型", "总分"] # 设置表格的列名
    for i in range(num):
        c = clist1[i]
        x.add_row([c[0], c[1], c[2], c[3], c[4]]) # 将每条学校排行榜数据逐一添加到表格中
    print(x) # 打印格式化后的表格

def main():
    cinfo = []
    url = "https://www.shanghairanking.cn/rankings/bcur/2020"
    html = get_dangdang_WebContent() # 获取网页内容
    extractList(cinfo, html) # 提取学校排行榜数据
    printList(cinfo, 3) # 打印前3条学校排行榜数据

if __name__ == '__main__':
    main()


运行结果如下:

2)心得体会

第一次写的这个作业是要求使用urllib.request和BeautifulSoup库来进行爬取,这次要求使用requests、BeautifulSoup库,所以对BeautifulSoup库更加熟悉了一些,解析HTTP文档和查找标签遍历方法;对使用requests库发送HTTP请求也多了解了一下。想着要跟输出信息差不多,所以又加了一个PrettyTable库,就可以将出结果制成表格。

作业②

1)实验

1.实验要求

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

2.代码

  • 选择爬取当当网,url=https://search.dangdang.com/?key=%CA%E9%B0%FC&act=input,关键词“书包”。

  • 首先定义了一个 scrape_dangdang() 函数,用于执行爬取操作。

  • 调用自定义的 askURL(url, headers) 函数发送 HTTP GET 请求,获取网页内容。这个函数使用了 requests 库发送请求,并将响应内容保存到文件中。

  • 使用 BeautifulSoup 对获取到的网页内容进行解析,创建一个 BeautifulSoup 对象,并指定使用 'html.parser' 解析器。

  • 通过分析网页 HTML 结构,使用 find_all() 方法提取符合条件的元素,即商品名称和价格。将提取到的数据分别存储在 goods_names 和 goods_prices 列表中。

  • 使用 PrettyTable 创建一个表格对象,并定义表格的列名。

  • 使用循环遍历商品名称列表和商品价格列表,并将每条商品信息添加到表格中。

  • 最后,打印输出格式化后的表格。

完整代码如下:

import requests
from bs4 import BeautifulSoup
from prettytable import PrettyTable  # 导入PrettyTable库,用于制作表格

def scrape_dangdang():
    dangurl = 'https://search.dangdang.com/?key=%CA%E9%B0%FC&act=input'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                      'ppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 QQBrowser/10.6.4209.400'
    }
    url = dangurl + '&page_index=1'  # 构造完整的URL
    html = askURL(url, headers)  # 发送HTTP GET请求获取网页内容
    soup = BeautifulSoup(html, 'html.parser')  # 使用BeautifulSoup解析HTML文档

    goods_names = []  # 存储商品名称的列表
    goods_prices = []  # 存储商品价格的列表

    # 提取商品名称数据
    for items in soup.find_all('p', attrs={'class': 'name', 'name': 'title'}):
        names = items.find_all('a')
        for name in names:
            title = name['title']
            goods_names.append(title)

    # 提取商品价格数据
    for items in soup.find_all('span', attrs={'class': 'price_n'}):
        goods_prices.append(items.string)

    table = PrettyTable(['序号', '商品名称', '商品价格'])  # 创建表格对象
    for i in range(len(goods_names)):
        table.add_row([i+1, goods_names[i], goods_prices[i]])  # 将每条商品信息添加到表格中

    print(table)  # 打印格式化后的表格

def askURL(url, headers):
    resp = requests.get(url, headers=headers)  # 发送HTTP GET请求获取网页内容
    resp.raise_for_status()  # 检查请求是否成功
    html = resp.content.decode('gbk')  # 解码网页内容
    with open("html.txt", "w", encoding='utf-8') as f:
        f.write(html)  # 将网页内容保存到文件中
    return html

if __name__ == '__main__':
    scrape_dangdang()


由于终端显示有限,分两次截图,共60条信息,运行结果如下:


2)心得体会

刚开始选择爬取的是淘宝,还想要实现翻页,但是反爬太厉害一直爬取不成功,很崩溃,就选择了当当网。这个代码实现爬取当当网里以“书包”为关键词搜索的一页商品信息,一页共有60条信息。虽然爬取成功但是输出的结构有些不尽人意,所以加上表格,但没想到还是有点差错,具体的商品名称、价格与表头对的不是很齐。对提取网页特定内容操作又熟悉了一次,即使用BeautifulSoup查找文档元素。对爬取网页流程编写代码也加深一遍理解。寻找目标网页、发送HTTP请求、获取网页内容、解析HTML、提取数据、数据处理和存储、遍历和翻页、异常处理等。应对反爬虫策略、对翻页操作还是不太行,但不会一直不行。

作业③

1)实验

1.实验要求

  • 要求:爬取一个给定网页( https://xcb.fzu.edu.cn/info/1071/4481.htm)或者自选网页的所有JPEG和JPG格式文件

  • 输出信息:将自选网页内的所有JPEG和JPG文件保存在一个文件夹中
    2.代码

  • url=https://xcb.fzu.edu.cn/info/1071/4481.htm

  • 运行该代码前需要确保已经在目录下事先创建了一个名为image的文件夹,用于保存图片

  • 导入urlparse、urljoin来处理url。

  • 定义函数get_photo(url):接受一个参数url,表示目标网页的链接。该函数用于从网页中提取图片链接并保存图片到本地。

  • 发送HTTP请求获取网页内容:使用requests.get()方法发送HTTP GET请求,将url和请求头部信息作为参数传递给该方法。获取到的响应存储在变量resp中。

  • 正则表达式提取图片链接:使用re.findall()方法,通过正则表达式提取出所有图片链接。正则表达式<img.?src="(.?)"用于匹配标签中的src属性的值,即图片
    链接。

  • 遍历图片链接并保存图片:使用enumerate()函数遍历图片链接列表,并使用urljoin()方法拼接正确的图片链接。然后,设置图片名称为递增的数字,使用
    requests.get()方法发送HTTP GET请求获取图片内容,并使用open()函数以二进制写入方式打开文件,将图片内容写入文件。

完整代码如下:

import requests
import re
from urllib.parse import urlparse, urljoin


def get_photo(url):
    # 设置请求头部信息,以模拟浏览器发送请求
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
    }
    resp = requests.get(url, headers=header)  # 发送HTTP GET请求获取网页内容
    resp.raise_for_status()  # 检查请求是否成功
    resp.encoding = resp.apparent_encoding  # 根据响应内容自动判断编码方式
    html = resp.text.replace("\n", "")  # 将换行符替换为空格,以便正则表达式匹配多行内容

    # 正则表达式提取所有图片链接
    ImageList = re.findall(r'<img.*?src="(.*?)"', html, re.S)
    for i, img in enumerate(ImageList):
        img_url = urljoin(url, img)  # 拼接正确的图片链接
        image_name = urlparse(img_url).path.split("/")[-1]  # 获取图片的有效文件名
        print(f"正在保存第{i + 1}张图片")

        resp = requests.get(img_url)  # 发送HTTP GET请求获取图片内容
        with open(f'image/{image_name}', 'wb') as f:  # 以二进制写入方式打开文件,保存图片内容
            f.write(resp.content)

    print(f"保存完成,请在image文件夹查看图片")


url = 'https://xcb.fzu.edu.cn/info/1071/4481.htm'
get_photo(url)

运行结果如下:

2)心得体会

再次复习正则表达式,成功写出提取图片链接的正则表达式;但是爬取不到图片,后来知道由于图片链接中包含了一些额外的查询参数,会导致文件保存时的命名问题,所以使用urlib.parse.urlparse来解析图片链接,然后获取有效的文件名,即img_url = urljoin(url, img),然后就出来了,.jpeg、.jpg都可以出来。之后再对代码输出提示修改一下,变得更合适一些,还有保存图片的命名方式。总的来说,对requests、BeautifulSoup、re多练习一次,就多熟悉一次。

posted @   lu_lu_l  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示