使用scrapy框架爬取中国各城市天气预报 实验

使用scrapy框架爬取中国各城市天气预报 实验

实验目的:

  1. 熟练安装 Python 扩展库 scrapy。

  2. 熟悉常见 HTML 标签的用法。

  3. 理解网页源代码结构。

  4. 理解 scrapy 框架工作原理。

实验内容:

安装Python扩展库 scrapy ,然 后 编 写 爬 虫 项 目 ,从网站http://www.weather.com.cn/shandong/index.shtml 爬取山东各城市的天气预报数据,并把爬取到的天气数据写入本地文本 weather.txt。

实验步骤:

  1. 在命令提示符环境使用 pip install scrapy 命令安装 Python 扩展库 scrapy。
  2. 在命令提示符环境使用 scrapy startproject sdWeatherSpider 创建爬虫项目
  3. 进入爬虫项目文件夹,然后执行命令 scrapy genspider everyCityinSD.py www.weather.com.cn 创建爬虫程序。
  4. 使用浏览器打开网址 http://www.weather.com.cn/shandong/index.shtml
  5. 找到下面位置

image-20221215013350328

  1. 在页面上单击鼠标右键,选择 “查看网页源代码”,按下F12打开开发者模式,然后找到与 “城市预报列表” 对应的位置。

image-20221215013633087

点击选中图中红框位置,然后鼠标移到红色箭头位置。

image-20221215013850940

我们的爬虫需要拿到每个城市的天气入口,这里可以用正则表达式<a title=".*?" href="(.+?)" target="_blank">(.+?)</a>匹配,后续会实现在代码里。

  1. 进入上图找到的济南天气
  2. 老方法,打开F12,选中图中红框位置,然后鼠标移到红色箭头位置,这时候会定位到这个卡片的源代码附近,分析一下。

image-20221215014242320

    1. 分析一下两张图image-20221215014417429image-20221215014427424

    2. 网页中的天气卡片是以ul标签包裹着,li标签存放着接下来七天的天气数据。

    3. 从左上图可以看到,我们找到了天气数据中的 date,cloud,当日气温,最低/高气温,风速风向

    4. 记住他们的Xpath位置,如,date也就是14日(今天),的Xpath。提取Xpath方式如下↓image-20221215015258587

    5. 那么这个date的Xpath为://*[@id="7d"]/ul/li[1]/h1 ,其他的元素以此类推,详情内容参见Xpath语法。

  1. 修改 items.py 文件,定义要爬取的内容。

import scrapy
class SdweatherspiderItem(scrapy.Item):
       # definethefieldsforyouritemherelike:
       # name=scrapy.Field()
       city=scrapy.Field()
       weather=scrapy.Field()

11.修改爬虫文件 everyCityinSD.py,定义如何爬取内容,其中用到的规则参考前面 对页面的分析,如果无法正常运行,有可能是网页结构有变化,可以回到前面的步骤重新 分析网页源代码。

from re import findall
from urllib.request import urlopen
import scrapy
from sdWeatherSpider.items import SdweatherspiderItem

class EverycityinsdSpider(scrapy.Spider):
    name = 'everyCityinSD'
    allowed_domains = ['www.weather.com.cn']
    start_urls = []
    # 遍历各城市,获取要爬取的页面
    url = r'http://www.weather.com.cn/guangdong/index.shtml'
    with urlopen(url) as fp:
        contents = fp.read().decode()
    pattern = '<a title=".*?" href="(.+?)" target="_blank">(.+?)</a>'
    for url in findall(pattern, contents):
        start_urls.append(url[0])

    def parse(self, response, **kwargs):
        # 处理每个城市的天气预报页面数据
        item = SdweatherspiderItem()
        city = response.xpath('//div[@class="crumbs fl"]//a[3]//text()').extract()[0]
        item['city'] = city
        # 每个页面只有一个城市的天气数据,直接取[0]
        # 存放天气数据
        selector = response.xpath('//ul[@class="t clearfix"]')[0]  
        weather = ''
        for li in selector.xpath('./li'):
            try:
                date = li.xpath('./h1//text()').extract()[0]
                cloud = li.xpath('./p[@title]//text()').extract()[0]
                high_tmp_list = li.xpath('./p[@class="tem"]//span//text()').extract()
                low = li.xpath('./p[@class="tem"]//i//text()').extract()[0]
                # 这里不加长度判断会导致找不到每日最高气温的时候抛出IndexError异常。
                if high_tmp_list.__len__() != 0:
                    tmp = high_tmp_list[0] + r'/' + low
                else:
                    tmp = low
                wind = li.xpath('./p[@class="win"]//em//span[1]/@title').extract()[0]
                wind = wind + li.xpath('./p[@class="win"]//i//text()').extract()[0]
                weather = weather + date + ':' + cloud + ',' + tmp + ',' + wind + '\n'
            except IndexError as e:
                continue
        item['weather'] = weather
        return [item]
  1. 修改 pipelines.py 文件,把爬取到的数据写入文件 weather.txt。
class SdweatherspiderPipeline:
    def process_item(self, item, spider):
      # 每一个段落执行完毕后都会调用此函数,所以文件写入模式为`a`,追加模式
        with open('weather.txt', 'a', encoding='utf8') as fp:
            fp.write(item['city'] + '\n')
            fp.write(item['weather'] + '\n\n')
        return item
  1. 修改 settings.py 文件,分派任务,指定处理数据的程序。
BOT_NAME = 'sdWeatherSpider'
SPIDER_MODULES = ['sdWeatherSpider.spiders'] 
NEWSPIDER_MODULE = 'sdWeatherSpider.spiders'
ITEM_PIPELINES = { 'sdWeatherSpider.pipelines.SdweatherspiderPipeline':1, }
  1. 接下来去验证

验证

  • scrapy项目根目录

image-20221215021845097

在项目根目录下执行命令scrapy crawl everyCityinSD 命令运行爬虫。

image-20221215022041424

我们去输出文件weather.txt里看看。vim weather.txt

image-20221215022255280

符合实验要求。

彩蛋

其实我爬取的是广东省每个市区的天气,我在上面的代码里面改了一个地方。你知道怎么改吗?

评论区告诉我~

  • 10
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LMAO6688

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值