IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 爬虫及数据预处理(链家+雾霾数据) -> 正文阅读

[Python知识库]爬虫及数据预处理(链家+雾霾数据)

数据预处理

1.通过爬虫爬取链家的新房数据,并进行预处理。

1.1 分析过程

1.1.1 爬取

? 首先进行数据的爬取,在爬取过程中,出现并解决了以下问题:

? 问题1:数据仅含有总价而不含有均价,且总价出现在均价的位置上

? 解决方案:判断均价位置数据内是否含有’-'符号,若含有则为总价数据,将其内容赋给总价,并将均价置空。

? 问题2:爬取数据不完整

? 解决方案:通过检查源网页,发现共有180条数据,但实际爬取到的数据少于这个数目。经过检查发现因为源网页存在一些数据项为空,比如没有房型信息等。对于这个问题,进行判断检查,对于空值额外处理即可。

? 问题3:反爬机制封禁ip

? 解决方案:在爬取过程中,经常遇到同样的代码时而成功爬取,时而爬取结果不完整或失败。对于这个问题,只需要在问题出现时,进入浏览器完成网页的人机验证即可解封被封禁的ip,完成后续的爬取。

1.1.2 数据预处理

? 完成爬取后,需要进行数据的预处理,分别进行去空格、设置数据类型、求总价相关信息和单价相关信息即可。

1.2 核心代码

1.2.1 spider.py

import scrapy
from test1.items import MyItem #从items.py中引入MyItem对象
class mySpider(scrapy.spiders.Spider):
    name = "lianjia" #爬虫的名字是lianjia
    allowed_domains = ["bj.lianjia.com/"] #允许爬取的网站域名
    start_urls = []

    for pg in range(1,23):
        url = "https://bj.fang.lianjia.com/loupan/pg{}/".format(pg)
        start_urls.append(url)

    def parse(self, response): #解析爬取的内容
        item = MyItem() #生成一个在items.py中定义好的Myitem对象,用于接收爬取的数据
        for each in response.xpath("/html/body/div[3]/ul[2]/*"):
            #用xpath来解析html,div标签中的数据,就是我们需要的数据。
            n = each.xpath("div/div[1]/a/text()").extract()[0]#/html/body/div[3]/ul[2]/li[1]/div/div[1]/a
            if len(n) == 0:  # 最小户型的数据可能不存在,进行判断,如果不存在,那么赋值为''
                item['name'] = ''
            else:
                item['name'] = n

            p1 = each.xpath("div/div[2]/span[1]/text()").extract()[0]
            if len(p1) == 0:  # 最小户型的数据可能不存在,进行判断,如果不存在,那么赋值为''
                item['location1'] = ''
            else:
                item['location1'] = p1

            p2 = each.xpath("div/div[2]/span[2]/text()").extract()[0]
            if len(p2) == 0:  # 最小户型的数据可能不存在,进行判断,如果不存在,那么赋值为''
                item['location2'] = ''
            else:
                item['location2'] = p2

            p3 = each.xpath("div/div[2]/a/text()").extract()[0]#/html/body/div[3]/ul[2]/li[1]/div/div[2]/a
            if len(p3) == 0:  # 最小户型的数据可能不存在,进行判断,如果不存在,那么赋值为''
                item['location3'] = ''
            else:
                item['location3'] = p3

            l0 = each.xpath("div/a/span[1]/text()").extract()#/html/body/div[3]/ul[2]/li[4]/div/a/span[1]
            if len(l0) == 0:  # 最小户型的数据可能不存在,进行判断,如果不存在,那么赋值为''
                item['shape'] = ''
            else:
                item['shape'] = l0[0]

            l1 = each.xpath("div/div[3]/span/text()").extract()#/html/body/div[3]/ul[2]/li[1]/div/div[3]/span
            if len(l1):  # 最小面积的数据存在时,进行提取最小值
                str = l1[0]
                startpos = str.find(" ") + 1
                endpos = str.find("-")
                if endpos == -1:
                    endpos = str.find("m")
                item['area'] = str[startpos: endpos]
            else:  # 最小面积不存在时,赋值为空串''
                item['area'] = ''

            l2  = each.xpath("div/div[6]/div[2]/text()").extract()#/html/body/div[3]/ul[2]/li[1]/div/div[6]/div[2]
            if len(l2): 
                totalPrice = ''
                for i in l2[0]:
                    if i.isdigit():
                        totalPrice += i
                    if i == "-":
                        break
                item['totalPrice'] = totalPrice
            else:
                item['totalPrice'] = ''

            l3 = each.xpath("div/div[6]/div[1]/span[1]/text()").extract()[0]
            endpos = l3.find("-")
            if endpos != -1:
                item['totalPrice'] = l3[:endpos]
                item['unitPrice'] = ''
            elif len(l3) == 0:
                 item['unitPrice'] = ''
            else:
                 item['unitPrice'] = l3

            if(item['name']): #去掉值为空的数据
                yield(item) #返回item数据给到pipelines模块

1.2.2 items.py

import scrapy

class MyItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field() #名称
    location1 = scrapy.Field()#地理位置
    location2 = scrapy.Field()
    location3 = scrapy.Field()
    shape = scrapy.Field()#房型
    area = scrapy.Field()#面积
    totalPrice = scrapy.Field()#总价
    unitPrice = scrapy.Field()#单价

1.2.3 pipelines.py

import csv
class MyPipeline:
    def open_spider(self, spider):
        try:
            self.file = open('lianjia.csv', 'w', newline='')
            self.csv = csv.writer(self.file)
        except Exception as err:
            print(err)

    def process_item(self, item, spider):
        self.csv.writerow(list(item.values()))
        return item

    def close_spider(self, spider):
        self.file.close()

1.2.3 lianjia_data_process.py

import pandas as pd

# 打开CSV文件
fileNameStr = 'lianjia.csv'
orig_df = pd.read_csv(fileNameStr, names=['name','location1','location2','location3','shape','area','totalPrice','unitPrice'],encoding='gbk', dtype=str)
print(orig_df.describe())

# 1.将字符串的列前后空格去掉
orig_df['name'] = orig_df['name'].str.strip()
orig_df['location1'] = orig_df['location1'].str.strip()
orig_df['location2'] = orig_df['location2'].str.strip()
orig_df['location3'] = orig_df['location3'].str.strip()
orig_df['shape'] = orig_df['shape'].str.strip()
orig_df['area'] = orig_df['area'].str.strip()
orig_df['totalPrice'] = orig_df['totalPrice'].str.strip()
orig_df['unitPrice'] = orig_df['unitPrice'].str.strip()

# 2.将aera,unitPrice,totalPrice变为浮点型
orig_df['area'] = orig_df['area'].astype(float)
orig_df['unitPrice'] = orig_df['unitPrice'].astype(float)
orig_df['totalPrice'] = orig_df['totalPrice'].astype(float)

# 3.总价
# 最大值
print("总价:")
imaxpos = orig_df['totalPrice'].idxmax()
print("最贵", orig_df.loc[imaxpos, "totalPrice"], orig_df.loc[imaxpos, "name"])
# 最小值
iminpos = orig_df['totalPrice'].idxmin()
print("最便宜", orig_df.loc[iminpos, "totalPrice"], orig_df.loc[iminpos, "name"])
# 中位数
print("中位数", orig_df['totalPrice'].median())

# 4.单价
# 最大值
print("单价:")
idmaxpos = orig_df['unitPrice'].idxmax()
print("最贵", orig_df.loc[idmaxpos, "unitPrice"], orig_df.loc[idmaxpos, "name"])
# 最小值
idminpos = orig_df['unitPrice'].idxmin()
print("最便宜", orig_df.loc[idminpos, "unitPrice"], orig_df.loc[idminpos, "name"])
# 中位数
print("中位数", orig_df['unitPrice'].median())

orig_df.to_csv("NewLianjia.csv", header=True, encoding="gbk", mode='w+', index=False,float_format='%.4f')

1.3 最终结果及分析结论

程序的输出如下:
在这里插入图片描述
csv前50条数据:

namelocation1location2location3shapeareatotalPriceunitPrice
京贸国际城·峰景通州武夷花园芙蓉东路1号(通燕高速耿庄桥北出口向南300米)1室6954068000.0000
观唐云鼎密云溪翁庄镇溪翁庄镇密溪路39号院(云佛山度假村对面)3室357106830000.0000
旭辉城房山房山其它北京市房山区良锦街6号院旭辉城营销中心2室7521928500.0000
檀香府门头沟门头沟其它京潭大街与潭柘十街交叉口3室12453043000.0000
中海丽春湖墅·合院昌平沙河地铁昌平线沙河地铁站南600米4室263100036000.0000
泰禾金府大院丰台西红门南四环地铁新宫站南800米4室362260075000.0000
电建地产洺悦苑丰台马家堡南四环中路115号3室8983063000.0000
金樾和著房山房山其它房山区良常路官道路口西800米3室8930034000.0000
和棠瑞著平谷平谷其它金海湖景区坝前广场西侧500米3室30553019000.0000
尊悦光华朝阳CBD北京市朝阳区光华东里甲1号院3号楼3室1332600130000.0000
北京城建北京合院顺义顺义其它燕京街与通顺路交汇口东800米(仁和公园南)3室9552047000.0000
珠光御景西园丰台丰台其它北京市丰台区长辛店长云路2号珠江御景营销中心3室11745039000.0000
北京城建北京合院顺义顺义其它燕京街与通顺路交汇口东800米(仁和公园南)4室21085045000.0000
金隅花石匠通州临河里砖厂北里链家门店2室8860533000.0000
国锐金嵿亦庄开发区亦庄荣华南路1号院5室285220080000.0000
首开香溪郡通州通州其它宋庄镇荷香街2号院5室9065035000.0000
天润福熙大道朝阳北苑清河营东路1号院, 清河营东路3号院6室4364542110000.0000
元熙华府丰台宋家庄东南三环东铁营桥向南600米3室126111387000.0000
京贸国际公馆通州九棵树(家乐福)怡乐中路299号院(广渠快速路二期出口向南1000米)1室7249064000.0000
凯德麓语昌平昌平其它兴寿镇京承高速G11出口向西怀昌路北侧3室28085035000.0000
新潮嘉园二期通州潞苑潞苑南大街185号1室6538458000.0000
长海御墅房山房山其它长沟国家湿地公园南侧3室22442023000.0000
中海云筑大兴大兴新机场北京市大兴区团结路3室8934037000.0000
中海云筑大兴大兴新机场京开高速庞各庄桥西1500米,团结路北(庞各庄镇宏轩饺子馆儿对面)3室26690037000.0000
远洋五里春秋石景山石景山其它五里坨黑石头路前行500m3室290100052024.0000
首创·河著顺义顺义其它京承高速11出口(昌金路)向东900 米路北4室248120041000.0000
华萃西山门头沟门头沟其它永定镇地铁S1号线石厂西南700米4室8366647000.0000
住总正华·时代广场大兴天宫院地铁4号线生物医药基地站南200米0室6140455000.0000
京西悦府房山阎村北京市房山区燕房线阎村地铁站东南角约189米3室17580050000.0000
中粮天恒天悦壹号丰台西红门南四环地铁新宫站南500米4室220190085000.0000
中海云熙大兴大兴其它魏善庄新城南中轴路东侧500米2室7630937700.0000
和光悦府朝阳朝阳其它南皋路和光悦府4室120106088000.0000
棠颂璟庐亦庄开发区亦庄开发区其它鹿华路7号院(南海子公园北侧500米)4室250190075000.0000
金隅上城郡昌平北七家北亚花园东路50米4室21293045000.0000
万科弗农小镇密云溪翁庄镇密关路西侧(密云水库南岸2公里)3室14035025000.0000
首开保利欢乐大都汇门头沟冯村石门营环岛北50米500325065000.0000
中铁华侨城和园大兴瀛海南五环南海子公园西侧约500米3室15495060000.0000
顺鑫颐和天璟顺义顺义其它新城右堤路与昌金路交汇处向北200米3室11036033000.0000
誉天下盛寓顺义中央别墅区中央别墅区榆阳路与林荫路交叉口3室12072060000.0000
泰禾金府大院丰台西红门南四环地铁新宫站南800米2室175170082000.0000
奥园雲水院密云溪翁庄镇密云区Y753(走石路)3室11125022000.0000
国瑞熙墅昌平北七家北七家镇岭上西路与定泗路交汇处东南角3室314150048000.0000
中粮京西祥云房山长阳地铁稻田站北800米,西邻京深路4室11580058000.0000
水岸壹号房山良乡良乡大学城西站地铁南侧800米,刺猬河旁3室185110058000.0000
观唐云鼎密云溪翁庄镇溪翁庄镇密溪路39号院(云佛山度假村对面)3室17249930000.0000
运河铭著通州北关商通大道与榆东一街交叉口,温榆河森林公园东500米2室10049049000.0000
万年广阳郡九号房山长阳长阳清苑南街与汇商东路交汇处西北角3室16683050000.0000
首开璞瑅公馆丰台方庄紫芳园五区3室2032200106000.0000
华远裘马四季门头沟大峪增产路16号院3室15695055000.0000

? 可以看到,程序成功完成了对网站的爬取,并完成了数据最大值、最小值和中位数的提取,成功达到了题目要求。

2.作业二:雾霾指数数据分析

2.1 分析过程

? 首先读入csv文件,而后对读入数据进行预处理如下:

? ① 删除含有空PM值的行

? ②计算PM平均值:分别计算每一天PM值的和、PM值的数目,而后通过前两个值计算平均值,将这三个数据作为三个新的列加入到表格中。

? ③通过groupby和mean计算PM指数年平均值和10-15年PM指数和温度月平均值的变化情况。

2.2 核心代码

beijing_weather_process.py

import pandas as pd
# 读取文件

filename = 'BeijingPM20100101_20151231.csv'
df = pd.read_csv(filename, encoding = 'utf-8')
# 删除有空PM值的行
df.dropna(axis=0, how='all', subset=['PM_Dongsi','PM_Dongsihuan','PM_Nongzhanguan', 'PM_US Post'], inplace=True)
# 计算PM平均值
df['PMsum'] = df[['PM_Dongsi','PM_Dongsihuan','PM_Nongzhanguan', 'PM_US Post']].sum(axis=1)
df['PMcount'] = df[['PM_Dongsi','PM_Dongsihuan','PM_Nongzhanguan', 'PM_US Post']].count(axis=1)
df['PMave']=round(df['PMsum']/df['PMcount'],2)
aveY_df = df.groupby('year').mean()
aveM_df = df.groupby(['year', 'month']).mean()

print(aveY_df.head())
# 删除不必要的列并将PM年平均值输出到文件
aveY_df.drop(list(aveY_df.columns[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]) , axis = 1 , inplace = True)
aveY_df.to_csv('PM_year_Ave.csv')
# 删除不必要的列并将PM和TEMP月平均值输出到文件
aveM_df.drop(list(aveM_df.columns[[0,1,2,3,4,5,6,7,8,9,10,12,13,14]]) , axis = 1 , inplace = True)
aveM_df.to_csv('PM_TEMP_month_Ave.csv')
# 输出PM年平均值
print(aveY_df)
print('------------------------------------------')
# 输出PM和TEMP月平均值
print(aveM_df)

2.3 最终结果及分析结论

? 最终生成两个csv文件,分别为’PM_year_Ave.csv’存储PM年平均值和’PM_TEMP_month_Ave.csv’存储PM和TEMP月平均值。

2.3.1 PM_year_Ave.csv

yearPMsumPMcountPMave
2010104.04571104.0457
201199.09324199.09324
201290.53877190.53877
2013338.67433.57996398.40268
2014358.04533.87681293.91771
2015306.4473.55764885.85894

2.3.2 PM_TEMP_month_Ave.csv

截取前50行如下:

yearmonthTEMPPMsumPMcountPMave
20101-6.3715690.40367190.40367
20102-1.9150597.23994197.23994
201032.99717994.04654194.04654
2010410.807880.07242180.07242
2010520.8534687.07191187.07191
2010624.49381109.03891109.0389
2010727.72984123.42611123.4261
2010825.3476397.68343197.68343
2010922.24145122.79271122.7927
20101012.28302118.78441118.7844
2010113.308735138.3841138.384
201012-2.0578797.11575197.11575
20111-5.5438344.8737144.8737
20112-0.85417150.29021150.2902
201136.96634657.99199157.99199
2011414.6964691.72067191.72067
2011520.7331565.10815165.10815
2011625.64416108.79471108.7947
2011726.46081107.38651107.3865
2011825.66375103.73381103.7338
2011919.226794.9694194.9694
20111013.19968145.55681145.5568
2011115.94965109.4351109.435
201112-2.30686108.72141108.7214
20121-4.94328118.92241118.9224
20122-2.5739184.44203184.44203
201235.06891996.47432196.47432
2012415.4631487.83588187.83588
2012521.9348890.96671190.96671
2012624.329196.63418196.63418
2012726.5595980.64971180.64971
2012825.5473581.16533181.16533
2012920.1151759.95225159.95225
20121013.3081194.95135194.95135
2012113.69197787.43696187.43696
201212-4.35342109.18731109.1873
20131-5.37568366.51891.939189183.1953
20132-1.82143331.44352.90625113.5665
201335.405914441.47983.767473114.5728
2013412.24861243.91673.88333363.04781
2013521.45565345.5433.89381789.14853
2013623.67778393.03063.533333111.3548
2013727.08221272.35983.63342374.93284
2013826.57124257.5433.83602267.92363
2013920.125329.64173.89027885.71788
20131012.82124388.21513.803763102.2088
2013115.913889339.32643.98333385.14629
201312-0.29301352.77153.84677490.31777
20141-0.91398424.02553.900538107.9117
20142-0.70238580.23663.816964160.5139

? 可以看到,程序成功完成了题目要求,生成了PM年平均值和PM-温度月平均值的变化情况表格。
3.890278 | 85.71788 |
| 2013 | 10 | 12.82124 | 388.2151 | 3.803763 | 102.2088 |
| 2013 | 11 | 5.913889 | 339.3264 | 3.983333 | 85.14629 |
| 2013 | 12 | -0.29301 | 352.7715 | 3.846774 | 90.31777 |
| 2014 | 1 | -0.91398 | 424.0255 | 3.900538 | 107.9117 |
| 2014 | 2 | -0.70238 | 580.2366 | 3.816964 | 160.5139 |

? 可以看到,程序成功完成了题目要求,生成了PM年平均值和PM-温度月平均值的变化情况表格。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:41:15  更:2022-02-07 13:41:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 0:21:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码