python3爬虫学习之beautifulsoup实战

记录一下beaautifulsoup的使用和信息提取规则,并运用在实战中,学习课程时做的案例

爬取中国天气网所有城市的最低气温并排出10大气温最低城市,实战中会有大大小小的误区及需要注意的地方,下面会一一列举

上代码

import requests
from bs4 import BeautifulSoup
# from pyecharts import Bar

cities_temp = []
#处理抓取页面
def parse_url(url):
    headers = {
        "User-Agent" : "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36"
                       " (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36"
    }
    resp = requests.get(url ,headers=headers)
    text = resp.content.decode("utf-8")
    soup = BeautifulSoup(text , "html5lib")
    conMidtab = soup.find_all("div" ,class_='conMidtab')[0]
    tables = conMidtab.find_all("table")
    for table in tables:
        trs = table.find_all("tr")[2:]
        for index,tr in enumerate(trs):
            cities = {}
            tds = tr.find_all("td")
            city_td = tds[0]
            if index == 0:
                city_td = tds[1]
            city = list(city_td.stripped_strings)[0]
            temp_td = tds[-2]
            min_temp = list(temp_td.stripped_strings)[0]
            cities["城市"] = city
            cities["最低温度"] = int(min_temp)
            cities_temp.append(cities)

def main():
    urls=[
        'http://www.weather.com.cn/textFC/hb.shtml',
        'http://www.weather.com.cn/textFC/db.shtml',
        'http://www.weather.com.cn/textFC/hd.shtml',
        'http://www.weather.com.cn/textFC/hz.shtml',
        'http://www.weather.com.cn/textFC/hn.shtml',
        'http://www.weather.com.cn/textFC/xb.shtml',
        'http://www.weather.com.cn/textFC/xn.shtml',
        'http://www.weather.com.cn/textFC/gat.shtml',
    ]
    for url in urls:
        parse_url(url)

    #分析数据排序
    cities_temp.sort(key=lambda data:data['最低温度'])
    data = cities_temp[0:10]
    # cities = list(map(lambda x:x["城市"],data))
    # temps = list(map(lambda x:x["最低温度"],data))
    # chart = Bar("中国最低温度城市排行榜")
    # chart.add('',cities,temps)
    # chart.render('phb.html')
    for d in data:
        for k,v in d.items():
            print(k + ": " + str(v))
        print("*"*30)


if __name__ == '__main__':
    main()

截取运行结果部分

分析网页时应该注意到,中国天气网分为华北,东北,港澳台等八个地区涵盖全国所有城市,我们把八个url放在列表中,遍历列表并调用分析网页的函数来提取我们需要的信息。

一:一般来说,我们解析网页时会使用这个

soup = BeautifulSoup(text , "html.parser")

或者这个

soup = BeautifulSoup(text , "lxml")

因为他们解析更快,但在本代码中用了这个

soup = BeautifulSoup(text , "html5lib")

原因是,在爬取港澳台时,网站的htnl语言有些不规范,有开始标签,没有结束标签,前两种解析会报错,无法获取我们需要的数据,而html5lib固然慢些,它也更强大,拥有极强的容错性和补全html标签代码的能力

二:我们分析网页时,可以看见7个div信息的class属性为conMidtab,是因为中国天气网给出了包括今天在内的七天数据,那么我们只需要今天的数据,那么我们应该给出下标取0操作,获取今天的信息。

三:我们在提取信息时,遍历标签获取信息,用到了enumerate,这个函数,它不仅仅遍历信息,还遍历下标,我们在获取华北地区信息时,可以看见提取是无误的,因为华北第一个是自治市,北京,北京的第一个地区是北京,像这样:

然而我们获取第二个地区,东北时就不一样了:

分析就能发现,华北能正常爬取,是因为北京和北京重名,而黑龙江和哈尔滨却非如此,也就是说,我们在华北获取的是北京市而非北京市的北京,我们把北京地区的气温信息给了北京市,在东北,把哈尔滨的天气信息给黑龙江就会出错。

因此,我们用enumerate获取下标,如果是第一个省或自治市,也就是第一个tr标签的下标为0时,那么第二个下标td标签为1才是真正的地区或城市的气温信息。

本人表达能力确实有限,不懂的可以多分析分析或者在下面探讨。

三:因为我们要获取气温最低的10个城市,所以在这里,把气温转化为int类型

cities["最低温度"] = int(min_temp)

四:剩下的就是把数据按温度排序,并做切片操作

cities_temp.sort(key=lambda data:data['最低温度'])
data = cities_temp[0:10]

我们用到sort函数,从低到高排序,还用到lambda表达式。

我们把“最低温度”这个key对应的value当做排序的key,而之前,我们已经把这个参数转化为了int类型

最后,排完序的list从低到高储存了所有的城市名称和最低气温,我们做切片操作,取[0:10]获取温度最低的10个城市

最后,我们打印出来。

最最后,关于代码中注释掉的内容,做的是数据可视化

以前是这样的,中间因为重装了一次系统,不知道为啥就报错了,只能先注释掉,努力解决中,代码是没问题的,有眉目的同学请告知一下,谢谢。

也希望能记录BeautifulSoup的提取规则。

最后补充一点,也算是重点,一般来说,获取抓取内容,以上文获取的resp为例

我们知道resp.text(),即可获取网页内容,这里要说明的是,爬取时,要打印出来以验证爬取内容无乱码现象,text()获取文本是自动解析,当网页编码不规范时,会有乱码。

本文代码是resp.content.decode("utf-8"),指定解码,希望了解到resp.text和resp.content的区别及用法。

猜你喜欢

转载自blog.csdn.net/s_kangkang_A/article/details/89048259
今日推荐