好 好 学 习,好 好 睡 觉

-->

数据采集第一次作业

作业1

实验过程

获取html

def getHTMLText(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        req = urllib.request.Request(url=url, headers=headers)
        resp = urllib.request.urlopen(req)
        data = resp.read().decode("utf-8")#解码
        return data
    except:
        return '异常'

通过正则寻找相关信息

通过审查元素,找到对应信息的位置,再分析其格式


# 正则找排名所在位置
reg_ranking = r'<div class="ranking" data-v-68e330ae>(.*?)</div>'  
res_ranking = re.findall(reg_ranking, data, re.S)   # 设置re.S模式
for i in res_ranking:
    # 替换其中的空格和换行
    i = re.sub(' ', '', i)
    i = re.sub('\n', '', i)
    ranking.append(i)
# 正则寻找全部层次
reg_level = r'<td data-v-68e330ae>.*?(前.*?%).*?</td>'  
res_level = re.findall(reg_level, data, re.S)  # 设置re.S模式
for i in res_level:
    level.append(i)
# 正则匹配学校名称
reg_name = r'<a href=".*" class="name-cn" data-v-b80b4d60>(.*)</a>'  
res_name = re.findall(reg_name, data)  # 不需要re.S
for i in res_name:
    name.append(re.sub('<.*>', '', i))  # 将<>包裹的东西都洗掉再添加
# 正则匹配学校总分
reg_score = r'<!----> <!----> <!----> <!----></div></div></td><td data-v-68e330ae>(.*?)</td>'  
res_score = re.findall(reg_score, data, re.S) # 设置re.S模式
for i in res_score:
    # 替换其中的空格和换行
    i = re.sub(' ', '', i)
    i = re.sub('\n', '', i)
    score.append(i)

运行结果

心得体会

  1. 为了不给对方服务器造成困扰,可以先将爬取的html保存下来,再对其进行解析。
  2. 在正则匹配过程中,经常出现匹配失败的情况(含不可见字符\n,\r等),可以通过设置re.S模式解决该问题。
  3. 因为存在中文字符,会出现字符对齐问题,使得输出不美观,通过使用chr(12288)插入调试,解决对齐问题。

作业2

  • 要求:用requests和Beautiful Soup库方法设计爬取https://datacenter.mee.gov.cn/aqiweb2/ AQI实时报。
  • 输出信息:
序号 城市 AQI PM2.5 SO2 No2 Co 首要污染物
1 北京 55 6 5 1.0 225
2......

实验过程

获取html

def getHTMLText(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        resp = requests.get(url=url, headers=headers)
        resp.encoding = resp.apparent_encoding  #解码
        return resp.text
    except:
        return '异常'

使用apparent_encoding,可以从内容分析出响应的内容编码方式

通过Beautiful Soup寻找数据

发现里边的数据非常的整齐,都在标签内

通过css选择获取其信息,发现一个城市相关信息有9条,便以9为一次循环存储相关信息。再用.text即可获取其信息

#构建soup对象
soup = BeautifulSoup(data, 'lxml')
soup.prettify()
tags = soup.select("td[style='text-align: center; ']")  # 通过css选择,得到以9个为一组的数据
cnt = 0  # 通过循环分别存储相应信息
for index in tags:
    if cnt % 9 == 0:
        city.append(index.text)
    elif cnt % 9 == 1:
        aqi.append(index.text)
    elif cnt % 9 == 2:
        pm25.append(index.text)
    elif cnt % 9 == 3:
        pm10.append(index.text)
    elif cnt % 9 == 4:
        so2.append(index.text)
    elif cnt % 9 == 5:
        no2.append(index.text)
    elif cnt % 9 == 6:
        co.append(index.text)
    elif cnt % 9 == 7:
        o3.append(index.text)
    elif cnt % 9 == 8:
        pollution.append(index.text.strip())  # 有\t ' '等,用strip()处理

    cnt = cnt + 1

运行结果

使用chr(12288)来调整结构

心得体会

通过使用requests请求获取html,再用BeautifulSoup进行解析,直接通过标签获取相关信息。感觉BeautifulSoup是蛮好用的,但是需要先对其结构有一定了解。

作业3

实验过程

获取html

分别用requests和urllib

使用requests:
def getHTMLText(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        resp = requests.get(url=url, headers=headers)
        # 解码比较奇特,utf-8是乱码,所以使用apparent_encoding,可以从内容分析出响应的内容编码方式
        resp.encoding = resp.apparent_encoding  
        return resp.text
    except:
        return '异常'
#使用urllib:
def getHTMLText_urllib(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        req = urllib.request.Request(url=url, headers=headers)
        resp = urllib.request.urlopen(req)
        data = resp.read()
        dammit = UnicodeDammit(data, ["utf-8", "gbk"])
        unicodeData = dammit.unicode_markup
        return unicodeData
    except:
        return '异常'

通过正则匹配相关信息

其图像地址都存在<img src=“......”中,故正则匹配能方便得匹配相关信息

def find_data():
    img_url = []  # 存放图片的url
    reg = r'<img src="(.*?)"' #获取所有的图像地址(包含了.jpg/.png等)
    res = re.findall(reg, data, re.S)  # 设置re.S模式。
    for i in res:
        if i[-3:] == 'jpg':  # 只需要.jpg文件,判断是否以jpg为结尾的图片
            img_url.append(url + i)  # 如果是.jpg结尾的图片,直接拼接url
    return img_url

保存图像到本地:

def Save_img(list):
    cnt = 1  # 控制循环,限制读取图片个数
    for i in range(len(list)):  # list的长度,图像个数
        resp = requests.get(list[i])
        f = open('./imgs/031904113_' + str(cnt) + '.jpg', 'wb')  # 二进制保存
        f.write(resp.content)  # 写入
        print('存入第' + str(cnt) + '张图片')
        cnt += 1

运行结果!


心得体会

这一题和之前爬取商品图片的相似,需要爬取图片的地址,一个相对简单的正则匹配便可以将他们整出来。

正则匹配最需要注意的地方便是换行等看不见的字符,一个小小的错误就会导致匹配失败。

可以通过在线正则调试自己的正则表达式是否正确,代替一次又一次的运行程序调试。

附上代码链接

posted @ 2021-09-30 19:27  bInbinL  阅读(97)  评论(0编辑  收藏  举报