新能源汽车可视化大屏数据展示系列之五数据
任务目标:
1.在mysql创建数据表
2.爬取数据到csv
3.清洗数据到mysql
创建模型,生产表到数据库
1 创建myApp应用
在原有Django项目carShow的控制台,执行指令:python manage.py startapp myapp
创建一个应用:
python manage.py startapp myApp 是一个常用的命令,用于在Django项目中创建一个新的应用(app)。这个命令会在项目目录下创建一个名为 myapp 的文件夹,并在其中生成一些基础文件,这些文件是Django应用的标准结构。
以下是这个命令会创建的文件和目录结构:
myApp/
migrations/
__init__.py
__init__.py
admin.py
apps.py
models.py
tests.py
views.py
management/
commands/
__init__.py
...
__init__.py:一个空文件,告诉Python这个目录是一个Python包。
admin.py:用于定义Django admin界面的定制。
apps.py:定义了一个配置类,用于配置Django应用。
models.py:定义数据库模型。
tests.py:用于编写测试用例。
views.py:定义视图函数和类。
management/commands/:用于存放自定义Django命令
2 增加模型层设置
在刚才创建的项目下面,找到models.py文件,增加模型类的编写:
from django.db import models
# Create your models here.
class CarInfo(models.Model):
id=models.AutoField('id',primary_key=True)
brand=models.CharField('品牌',max_length=250,default='')
carName=models.CharField('车名',max_length=250,default='')
carImg=models.CharField('图片链接',max_length=250,default='')
saleVolume=models.CharField('销量',max_length=250,default='')
price=models.CharField('价格',max_length=250,default='')
manufacturer=models.CharField('厂商',max_length=250,default='')
rank=models.CharField('排名',max_length=250,default='')
carModel=models.CharField('车型',max_length=250,default='')
energyType=models.CharField('能源类型',max_length=250,default='')
marketTime=models.CharField('上市时间',max_length=250,default='')
insure=models.CharField('保修时间',max_length=250,default='')
createTime=models.DateField('创建时间',auto_now_add=True)
class Meta:
db_table='carInfo'
这段代码定义了一个名为 CarInfo
的 Django 模型,用于表示汽车信息。以下是对每个字段和相关配置的解释:
- id:
- 类型:
AutoField
- 说明:这是一个自动递增的主键字段,用于唯一标识每一条记录。
- 参数:
primary_key=True
表示这是主键。
- brand:
- 类型:
CharField
- 说明:表示汽车品牌。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- carName:
- 类型:
CharField
- 说明:表示汽车名称。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- carImg:
- 类型:
CharField
- 说明:表示图片链接(注意这里可能是一个错误,通常应该是销量)。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- price:
- 类型:
CharField
- 说明:表示汽车价格(注意这里可能是一个错误,通常应该是价格)。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- manufacturer:
- 类型:
CharField
- 说明:表示汽车厂商。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- rank:
- 类型:
CharField
- 说明:表示汽车排名(注意这里可能是一个错误,通常应该是价格)。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- carModel:
- 类型:
CharField
- 说明:表示汽车车型。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- energyType:
- 类型:
CharField
- 说明:表示汽车能源类型(如汽油、电动等)。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- marketTime:
- 类型:
CharField
- 说明:表示汽车上市时间。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- insure:
- 类型:
CharField
- 说明:表示汽车保修时间/或里程数量。
- 参数:
max_length=250
表示最大长度为250个字符,default=''
表示默认值为空字符串。
- createTime:
- 类型:
DateField
- 说明:表示记录创建的时间。
- 参数:
auto_now_add=True
表示在创建记录时自动设置为当前日期和时间。
- Meta:
db_table='carInfo'
:指定数据库中对应的表名为carInfo
。
注意事项
saleVolume
,price
,rank
这些字段的名称可能与实际含义不符,建议检查并更正。例如,saleVolume
应该改为salesVolume
,price
应该改为price
,rank
应该改为ranking
。- 如果需要存储数值数据(如价格、销量),应使用适当的字段类型,如
DecimalField
或IntegerField
》》》多学一招
在 Django 中,Meta
类是一个特殊的内部类,用于定义模型的元数据。这些元数据可以影响模型的行为和数据库表的映射方式。
在例子中:
class Meta:
db_table = 'carInfo'
这个 Meta
类中的 db_table
属性指定了该模型对应的数据库表的名称。默认情况下,Django 会根据模型的名称自动生成数据库表名,通常是 appname_modelname
的形式。然而,通过设置 db_table
属性,你可以自定义数据库表的名称。
具体来说,这段代码告诉 Django,当你对这个模型进行数据库操作时,应该使用名为 carInfo
的数据库表,而不是默认生成的表名。这在以下几种情况下特别有用:
- 已有数据库:如果你正在使用一个已经存在的数据库,并且表名与 Django 默认生成的名字不同,你可以通过这种方式来匹配现有的表。
- 命名规范:你可能希望使用特定的命名规范来使数据库表名更具可读性或符合某些业务需求。
- 避免冲突:在某些情况下,默认生成的表名可能会与其他表名产生冲突,通过自定义表名可以避免这种情况。模仿上述代码,编写User的模型类:
class User(models.Model):
id=models.AutoField('id',primary_key=True)
username=models.CharField('用户名',max_length=250,default='')
password=models.CharField('密码',max_length=250,default='')
class Meta:
db_table='user'
3 在mysql生成数据表
为了在mysql中生成相应的表,需要在settings.py添加“myApp":
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
]
在terminal下执行指令:python manage.py makemigrations
python manage.py makemigrations
是 Django 框架中的一个命令,用于创建数据库迁移文件。这些迁移文件记录了模型(models)的更改,以便在数据库中应用这些更改。
以下是这个命令的具体作用和步骤:
- 检测模型变化:
makemigrations
会检查你的 Django 项目中的模型定义(位于models.py
文件中),并与当前数据库结构进行比较。 - 生成迁移文件: 如果检测到模型的变化(例如新增字段、删除字段、修改字段类型等),Django 会自动生成相应的迁移文件。这些文件通常位于每个应用的
migrations
目录下,文件名以数字开头,表示迁移的顺序。 - 记录迁移操作: 迁移文件包含了具体的数据库操作指令,如
CREATE TABLE
,ALTER TABLE
,DROP TABLE
等。这些指令描述了如何将数据库从旧状态更新到新状态。
在terminal下执行指令:python manage.py migrate
使用navicat查看carData数据库下的表:
数据爬取和清洗
分析排行的url变化:
#前10条
https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&city_name=%E5%8C%97%E4%BA%AC&count=10&offset=0&month=&new_energy_type=&rank_data_type=11&brand_id=&price=&manufacturer=&series_type=&nation=0
#前11-20条
https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&city_name=%E5%8C%97%E4%BA%AC&count=10&offset=10&month=&new_energy_type=&rank_data_type=11&brand_id=&price=&manufacturer=&series_type=&nation=0
接下来回到spiderMain项目目录,在spider.py文件下,过滤数据到csv文件。增加的代码是try 块,及下面的代码部分。
def main(self):
#定义变量count
count=self.get_page()
print(count)
params={'offset':int(count)}
# print("数据从{}开始爬取".format(int(count)+1))
#pageJson=requests.get(self.spiderUrl, headers=self.headers).json()
pageJson=requests.get(self.spiderUrl, headers=self.headers,params=params).json()
pageJson=pageJson["data"]["list"]
# print(pageJson)
try:
# 循环遍历
for index, car in enumerate(pageJson):
carData = []
print('正在爬取第%d' % (index + 1) + '数据')
# 品牌名 print(car['brand_name'])
carData.append(car['brand_name'])
# 车名 print(car['series_name'])
carData.append(car['series_name'])
# 打印图片链接print(car['image'])
carData.append(car['image'])
# 销量
carData.append(car['count'])
# 价格,需要拼接最低价格和最高价格;
price = []
price.append(car['min_price'])
price.append(car['max_price'])
carData.append(price)
#厂商 print(car["sub_brand_name"])
carData.append(car["sub_brand_name"])
# 排名 https://www.dongchedi.com/auto/params-carIds-x-5952
# print(car['rank'])
carData.append(car['rank'])
# 5952,变成活的数据
carNumber = car['series_id']
infoHTML = requests.get('https://www.dongchedi.com/auto/params-carIds-x-%s' % carNumber,
headers=self.headers)
# print(infoHTML.text)
infoHTMLPath = etree.HTML(infoHTML.text)
# carModel
carModel = infoHTMLPath.xpath('//div[@data-row-anchor="jb"]/div[2]/div/text()')[0]
carData.append(carModel)
# 新能源汽车类型 fuel_form
energyType = infoHTMLPath.xpath('//div[@data-row-anchor="fuel_form"]/div[2]/div/text()')[0]
carData.append(energyType)
# maketTime
marketTime = infoHTMLPath.xpath("//div[@data-row-anchor='market_time']/div[2]/div/text()")[0]
carData.append(marketTime)
# 保修期限 insure
# infoHTMLpath.xpath("//div[@data-row-anchor='period']/div[2]/div/text()")[0]
insure = infoHTMLPath.xpath('//div[@data-row-anchor="period"]/div[2]/div/text()')[0]
carData.append(insure)
print(carData)
self.save_to_save(carData)
# 等待存入csv文件之后,再去掉break
# break
except:
pass
#之前的设置页面和调用
self.setPage(int(count)+10)
self.main()
经过运行发现一直从1-10,下次再从1-10,出现bug的原因在于
https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&city_name=%E5%8C%97%E4%BA%AC&count=10&offset=0&month=&new_energy_type=&rank_data_type=11&brand_id=&price=&manufacturer=&series_type=&nation=0
#将offset=0给去除掉
https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&city_name=%E5%8C%97%E4%BA%AC&count=10&month=&new_energy_type=&rank_data_type=11&brand_id=&price=&manufacturer=&series_type=&nation=0
- 点赞
- 收藏
- 关注作者
评论(0)