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

发布时间 2023-09-23 19:36:53作者: Qu-YaPeng

作业①

爬取大学排名实验

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

    输出信息:

    排名 学校名称 省市 学校类型 总分
    1 清华大学 北京 综合 852.5
    2 *** *** *** ***
  • 具体实现
    代码思路:

    1. 导入需要的模块:urllib.request用于发送HTTP请求,bs4用于解析网页内容。
    2. 定义函数get_HTML(url)来获取指定URL的网页内容。首先使用urllib.request.Request()创建一个请求对象,然后使用urlopen()方法发送HTTP GET请求并读取响应。最后将响应内容解码为字符串,并返回。
    3. 观察页面标签元素找到所需的标签("tbody"、"a"、"td"、"tr"),并使用.text.strip()方法获取元素的文本内容。最后将提取的数据作为列表添加到传入的list列表中。
    4. 定义函数data_print(list1, num)来打印解析的数据。使用格式字符串tplt来定义输出的格式,然后使用.format()方法来填充格式字符串。

    代码展示:

import urllib.request
import bs4
from bs4 import BeautifulSoup

#获取网页信息
def get_HTML(url):
    url="http://www.shanghairanking.cn/rankings/bcur/2020"
    #访问网站
    req = urllib.request.Request(url)
    data = urllib.request.urlopen(req)
    #读取信息 并且转码
    data = data.read().decode()
    return data
#解析网页数据
def data_HTMl(list,html):
    soup = BeautifulSoup(html,"html.parser")
    #用 soup.find("tbody") 找到 HTML 中的 <tbody> 元素(大表格)
    #使用 children 属性遍历 <tbody> 元素的子元素(即表格的行)
    for tr in soup.find("tbody").children:
        #首先使用 tr("a") 获取行中的 <a> 元素(清华大学名字),然后使用 tr("td") 获取行中的所有 <td> 元素。
        a = tr("a")
        #通过索引访问所需的 <td> 元素,并使用 .text.strip() 方法获取元素的文本内容。.strip() 方法用于去除文本内容的首尾空白字符。
        tds = tr("td")
        #将提取的数据作为列表 [tds[0].text.strip(), a[0].string.strip(), tds[2].text.strip(), tds[3].text.strip(), tds[4].text.strip()] 添加到传入的 list 列表
        list.append([tds[0].text.strip(), a[0].string.strip(), tds[2].text.strip(),
                    tds[3].text.strip(), tds[4].text.strip()])
def data_print(list1,num):
    #定义了一个格式字符串 tplt、五个占位符
    #^:表示居中对齐 10、12:表示该项的宽度为 10 或 12 个字符。\t:表示添加一个制表符(Tab) {0}、{1}、{2}、{3}、{4}代表参数
    tplt = "{0:^10}\t{1:^10}\t{2:^12}{3:^10}\t{4:^10}"
    print(tplt.format("排名", "学校名称", "省份", "学校类型","总分"))
    for i in range(num):
         u = list1[i]
         print(tplt.format(u[0], u[1], u[2], u[3], u[4]))
    print()
    print("以上共有记录" + str(num) + "条。")

def main():
    uinfo = []
    url="http://www.shanghairanking.cn/rankings/bcur/2020"
    html = get_HTML(url)
    data_HTMl(uinfo, html)
    data_print(uinfo, 30)
if __name__ == '__main__':
    main()

运行结果:

心得体会

第一次将理论知识运用到实践中,学习了解掌握urllib.request模块和BeautifulSoup模块,学习了格式化输出。

作业②

爬取商城网站“书包”名称和价格实验

  • 实验要求
    用requests和re库方法设计某个商城(自已选择)商品比价定向爬虫,爬取该商城,以关键词“书包”搜索页面的数据,爬取商品名称和价格。
  • 具体实现
    代码思路:
  1. 通过requests库发送GET请求获取网页内容。使用BeautifulSoup库解析网页内容。
  2. 使用soup.find_all()方法查找所有的商品价格标签(div)和商品名称标签(em)。分别保存在ptl和tlt两个变量中。
  3. 通过find()方法提取相关信息。

代码展示:

import re
import requests
from bs4 import BeautifulSoup
#网站地址
url = 'https://search.jd.com/Search?keyword=%E4%B9%A6%E5%8C%85&enc=utf-8&wq=shu%27bao&pvid=d692d49a9e864669b9fd7961c3e722db'
header = {
    'referer': 'https://search.jd.com/Search?keyword=%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8&spm=2.1.1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31',
    'cookie': 'shshshfpa=b5f36314-1742-1b85-8dcc-7045fdb3b4b5-1667349047; shshshfp=d547487362f8a6082adcbdf3f8748720; __jdu=364192152; 
shshshfpx=b5f36314-1742-1b85-8dcc-7045fdb3b4b5-1667349047; areaId=16; ipLoc-djd=16-1303-0-0; PCSYCityID=CN_350000_350100_0; _pst=jd_72bed13713c96; unick=jd_72bed13713c96; pin=jd_72bed13713c96; _tp=N5vAmU920Z0wbF6I0MxZgBYl7tjV9aBt19PUT89D7lY%3D; qrsc=3; 
unpl=JF8EAJdnNSttXUxTAh5SGEEXTlxcW11bGB9WPW9VUA5cSVQDSQUZEhB7XlVdXxRKHx9sZxRUWVNKXA4aBysSEXteU11bD00VB2xXXAQDGhUQR09SWEBJJVlQXl4ITxUBbWQ1ZF5Ye1QEKwAcFxBDXlRaXjhKJwRfVzVWVVBJVQErAysTIAkJCFdbD08QAyJlAlFdUEhUARgyGiIT; 3AB9D23F7A4B3CSS=jdd03PVSUU54GGAR7IS32R4IMPHTLBYLZSAZD5OE4XPILF3NP7UMO6R5KVGJ23F42ULJUR5M64BDWTJ6R6FW5EINCGAYPCEAAAAMKW2JCNXQAAAAACBN7HRYKVQ76XQX; _gia_d=1; thor=5D81B6E91112E015439696EBF36804B9BA3575017FF5A1DB5D1C752992A994FF23F66A3491AB073A37FA95F9B6099554E9EC7E9768AA7A511D0E4719926A6C7DB3B0A0C8AD63D58E7639DB5A0078F36100B40784E68DDB163E845E5F846EDAB899AF970438D505EA47B4F724280BE76ADE7304910DAB139363E26E681C3C9E177F70204B047D56A4BA948E7960D9E80FA851F6EFC41547D93646AE0C9A802711; flash=2_cZgzxUebndUc2BIE6Acj7tuSV1jzlKb2rb_lYf7BNH55y0-MHXWsEK3dDScGBuc9i_lpTHcOsBRvrK4djPmkhazG7-MLGdPivVAoj7_2qzh*; pinId=ekKCf6hCeW6dex9nNIEGKLV9-x-f3wj7; __jdv=76161171|haosou-search|t_262767352_haosousearch|cpc|5512153332_0_46664a2b640941bb9dc9a5b5317c6311|1695280167076; xapieid=jdd03PVSUU54GGAR7IS32R4IMPHTLBYLZSAZD5OE4XPILF3NP7UMO6R5KVGJ23F42ULJUR5M64BDWTJ6R6FW5EINCGAYPCEAAAAMKW2JCNXQAAAAACBN7HRYKVQ76XQX; jsavif=0; jsavif=0; rkv=1.0; shshshsID=95a68db43c9719f530669ed6bebed6c7_3_1695280175229; __jda=122270672.364192152.1693390633.1694944463.1695280146.4; __jdb=122270672.4.364192152|4.1695280146; __jdc=122270672; shshshfpb=AAoeWkraKEvNjFBdCG4WNzHBF_bO0tRZnNJBHSQAAAAA; 3AB9D23F7A4B3C9B=PVSUU54GGAR7IS32R4IMPHTLBYLZSAZD5OE4XPILF3NP7UMO6R5KVGJ23F42ULJUR5M64BDWTJ6R6FW5EINCGAYPCE'  
}

r = requests.get(url, headers=header)
soup = BeautifulSoup(r.text, "html.parser")
#查找所有商品价格标签
ptl = soup.find_all('div', 'p-price')
#查找所有商品名称标签
tlt = soup.find_all('div', 'p-name p-name-type-2')
#{:<6s} 表示将第一个字符串(序号)左对齐,并占据 6 个字符的宽度。
#{:<40s} 表示将第二个字符串(商品名称)左对齐,并占据 40 个字符的宽度。
#{:^10s} 表示将第三个字符串(价格)居中对齐,并占据 10 个字符的宽度。
# print('{:<6s}{:<80s}{:^30s}'.format('序号', '商品名称', '价格'))
for i in range(len(tlt)):
    #提取商品名称 <em>商品标签
    title = tlt[i].find('em').text
    price = ""
    if len(ptl) > 0:
        #提取商品价格![](https://img2023.cnblogs.com/blog/3286129/202309/3286129-20230922112629020-380225735.png)

        price_tag = ptl[i].strong.i
        if price_tag:
            #提取价格标签内的文本内容,并使用 .strip() 方法去除首尾的空格。
            price = price_tag.text.strip()
    print(f"商品名称:{title}")
    print(f"商品价格:{price}")
    print("-------------------------")
    # print('{:<6d}{:<80s}{:^10s}'.format(i+1, title, price))

运行结果:

心得体会

这次实验与上次实验的区别之处是使用了CSS选择器,通过使用soup.find_all()方法结合CSS选择器,可以方便地定位和提取HTML文档中的特定标签和内容,这种方式更灵活高效。

作业③

爬取网站照片实验

  1. 获取网页内容,并用BeautifulSoup进行解析。
  2. 创建文件夹来保存图片。
  3. 查找所有"img"标签,来获取图片链接,并根据后缀进行拼接保存。

代码展示:

import os
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse

# 定义要爬取的网页URL
url = 'https://xcb.fzu.edu.cn/info/1071/4481.htm'

# 发送HTTP GET请求获取网页内容
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

# 创建保存图片的文件夹
folder_path = 'image_folder'  # 文件夹路径
if not os.path.exists(folder_path):
    os.makedirs(folder_path)

# 查找所有img标签
img_tags = soup.find_all('img')
for img_tag in img_tags:
    # 获取图片链接
    img_url = img_tag.get('src')
    if img_url and (img_url.endswith('.jpeg') or img_url.endswith('.jpg')):
        # 构建图片的完整URL
        full_img_url = urljoin(url, img_url)
        # 提取图片文件名
        img_filename = os.path.basename(urlparse(full_img_url).path)
        # 拼接图片保存路径
        save_path = os.path.join(folder_path, img_filename)
        # 发送HTTP GET请求获取图片内容
        img_response = requests.get(full_img_url)
        # 保存图片到本地
        with open(save_path, 'wb') as f:
            f.write(img_response.content)

        print(f'保存图片: {img_filename}')

print('所有JPEG和JPG文件已保存在文件夹中。')

运行结果:

心得体会

这次主要是url的处理,例如使用 urljoin() 将相对URL转换为绝对URL,使用 urlparse() 提取URL的各个部分,再根据后缀名进行图片路径的拼接。这部分知识点是我需要加强学习的地方。