基于Scrapy框架对二手车数据进行挖掘


基于个人的项目来把自己的一些经验分享给大家,其中个别图片和文字是来源于互联网,就不一一标注了。
不保证完全正确。

理论知识及框架、包介绍

Scrapy框架:爬取数据,提取结构性数据的应用框架

它包括引擎、调度器、下载器、爬虫(Spider)、Item容器五大组件。

可以应用在数据挖掘、信息处理或存储历史数据等一系列的程序中
最初是为了页面抓取所设计,也可以应用在获取API所返回的数据(例如AAMS)或者通用的网络爬虫

组件之间通过数据流通讯(绿色部分)
Spider->Engine->Scheduler->Downloader:(request数据)
Downloader->Engine->Spider->ItemPipeline:(response数据)
在这里插入图片描述

一、Spider:存放爬虫程序,包括回调函数(处理response数据函数)
(1)需要request的网页放在Spider,然后提供给引擎
(6)接受引擎发送的数据,用回调函数并分析


二、引擎:Scrapy的核心,数据所有组件之间的数据流动。
(2)将Spider发过来的网页(request)给调度器
(5)将下载器发送的数据再传给Spider,供其分析

三、调度器:负责调度
(3)从引擎接受网页(request),再转给下载器。

四、下载器:下载网页内容
(4)获得调度器发过来的网页,提取其中的数据(response),再发给引擎

五、item容器:定义结构性数据,并对数据进行数据库存储
(7)负责处理 Spider提取出来的Item(容器,存放需要的内容) 进行存储化(如存放到数据库或文件)


其他中间件:提供一个简便的机制,通过插入一个定义的代码来扩展Scrapy的功能

下载器中间件:特定hook(钩子),用于处理下载器发送到引擎的response

Spider中间件:处理引擎和Spider交互的一个hook,将引擎出来的reponse数据过滤和一些额外的操作,再给Spider
同时接受SPiders的输出(request请求和item的输出) 并过滤




实战

1、二手车网站选取:二手车之家

尝试找了一些网站,最终找到二手车之家,这个网站的数据信息比较全面。

相对于人人二手车网站,其信息更加正确,人人二手车有相当数量的假数据和脏数据,后期会造成很大的处理和分析困难。

相对于瓜子二手车网站,其反爬虫机制还不健全,利于我们对数据进行有效及时的爬取和保存。

对于以上两个网站,针对其设置的反爬虫机制,我们需要改变User Agent 和设置访问间隔,这既会造成我们代码编写困难,也会导致数据收集的速度大大下降。



2、编写爬虫项目

2.1 创建项目

1.首先我们在cmd窗口下,在桌面创建我们的scrapy项目model:

C:\Users\15650>cd desktop

C:\Users\15650\Desktop>scrapy startproject  model

2(可选,帮助我们自动生成爬虫文件,也可手动设置)(爬虫名one 默认爬虫网站 taoche.com);

C:\Users\15650\Desktop>cd model

C:\Users\15650\Desktop\model>scrapy genspider one che168.com



2.2 编写爬虫程序

思想:基于BFS爬取策略,爬取二手车数据。

首先Scrapy自动urllib.request网页然后把response网页数据传给回调函数。

回调函数对整个html网页内容,然后使用xpath提取网页内容中所需要的信息。

包括:二手车名称,二手车价格(万元),比新车省的价格(万元),商家名称,行驶里程(万公里),首次上牌时间,’
‘所在地,发布时间,年检到期日期,保险到期日期,排放标准,过户次数,’
'维修保养,车辆说明,发动机,变速器,车辆级别,颜色,燃油标号,驱动方式,采集网址

然后把所有信息都存放到ITem数组,再提交给pipeline,然后存储到数据库中。



2.3数据清理

将数据库中文件保存到本地Excel文件,然后利用Jyputer Notebook读取并进行预处理。

包括去重和数据标准化。

数据清洗,并将正常数据分为测试集(500个)和训练集(测试集合以外的所有)。

包括:删除重值、删除网址和说明、滤除缺失数据、删除所有带"-"的行、把时间戳转换为正常字符串,将上牌时间戳转为正常时间,将未上牌删除、删除属性值的前后空格。

并删除异常价格。
数据清洗之后,将正常数据分为测试集(500个)和训练集(测试集合以外的所有),然后在保存为本地文件。



2.4数据线性分析

利用面向对象的思想来进行二手车数据属性的线性关系,包括属性的占比:例如城市占比、不同车型占比;
和属性线性关系的分析:比如价格和车型的关系,降价和行驶里程的问题。

利用pyecharts显示出来。

其中遇到的未知原因错误有:
python-关于报错cannot import *** from pyecharts的问题

可以尝试先卸载,然后换个镜像重新安装:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyecharts

重装完再imoprt pyecharts可能出现no module named 'pyecharts_snapshot’的报错:
这时同样安装上面的方法安装pyecharts_snapshot即可:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyecharts_snapshot

具体原因不详,但是实测有效,大神看到解答一下!



机器学习初探索

利用KNN算法对价格范围作一个预测,实现机器学习的初步探索。
KNN(K近邻算法):最简单的分类算法
K近邻(k-Nearest Neighbor,KNN)分类算法的核心思想是如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
KNN算法可用于多分类,KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,作为预测值。

实战-初探索(dmoz,开放式分类目录网站,也就是导航网站)

download book和resource

使用Scrapy抓取一个网站一共需要四个步骤
1):创建一个Scrapy项目
2):定义Item容器
3):编写爬虫
4):存储内容


1.创建Scrapy新项目:

cmd窗口下

cd desktop

scrapy startproject 新项目名

配置文件:scrapy.cfg

子文件夹:存放模块的代码
items、pipeline对应框架图中的两个同名组件、settings(设置文件)、子文件夹spiders(对应同名流程图中组件)



2.定义Item容器

item:保存爬取到的数据的容器,使用方法和python字典类似,并且提供了额外保护机制来避免拼写错误导致的未定义字段的错误

首先对需要获取的数据进行建模(资源名字、资源超链接、资源描述):在items.py里面建立相应的字段

 # name = scrapy.Field()
 name:需要建立字段的名字
 scrapy.Field():需要的占位符

item容器:

import scrapy

class DmozItem(scrapy.Item):
    title = scrapy.Field()
	link = scrapy.Field()
	desc = scrapy.Field()


3.编写爬虫(编写Spiders类)

Spiders:用户编写用于从网站上爬取数据的类
包含一个用于下载的初始url,然后是如何跟进网页中的链接以及如何分析页面中的内容,还有提取生成item方法

在cmd窗口项目中:scrapy genspider dmoz dmoz.org
自动在spiders文件中生成dmoz.py
或者手动生成

dmoz.py代码

import scrapy


class DmozSpider(scrapy.Spider):
    name = 'dmoz'   #用来确认蜘蛛的名字
    allowed_domains = ['dmoztools.net']  #蜘蛛要爬取的范围(只会爬该列表里面的链接)
    start_urls = [
	    'http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/',
	    'http://www.dmoztools.net/Computers/Programming/Languages/Python/Resources/'
	             ]#需要开始爬取的网址

    def parse(self, response):  #分析的方法   筛选出item对应的数据
	#reponse.url应该是列表
        filename = response.url.split("/")[-2]  #保存成两个文件(使用split分片,截取倒数第二个字符串)
        with open(filename,'wb') as f:
                f.write(response.body)

#在根目录生成两个网页的源代码

爬取:
项目cmd窗口:scrapy crawl dmoz调用爬虫dmoz 去工作

流程:
1)需要request的网页存放在Spider,然后提供给引擎

2)引擎将Spider发送过来的网页(request数据) 发送给调度器

3)调度器从引擎接受网页(request数据),再转给下载器
然后获取页面的数据(response),发送给引擎,再提供给Spider分析。



4.存储内容下载器获得调度器的网页数据(request)。

Spider分析下载的response(用dmz.py中的分析方法parse)
并提取出item和需要跟进的url 的类(将网页的内容提取出我们需要的数据)

Scrapy Selectors(选择器):Select是一个选择器,有四个基本方法

1.xpath():传入xpath表达式,返回该表达式所对应的的所有节点的select list列表
xpath:一门在网页中查找特定信息的语言,用来筛选数据(比正则简单),解析html/xml对象。


2.css():传入css表达式,返回该表达式所对应的所有节点的selector list列表

3.extract():序列化该节点为unicode字符串并返回list

4.re():根据传入的正则表达式对数据进行提取。返回unicode字符串list列表

在Scrapy中不使用正则表达式,而是使用一种基于Xpath和CSS的表达式机制:Scrapy Selectors。



进入网址对应的Scrapy Shell
cmd项目窗口下:scrapy shell "http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/"

进入后得到了reponse响应对象,可以尝试输出response.body或response.headers

尝试从其中获得 title、link、disc。用select选择器的四个方法来进行筛选

response.xpath(’//title’) :返回Selector对象的一个列表
字符串化: response.xpath(’//title’) .extract()
得到里面的文字:response.xpath(’//title/text()’)


shell里面会根据初始化的类型自动定义一个sel变量(可能等同于response)

快速获取xpath:审查元素,相应字段右键copy->copy xpath 复制粘贴

sites=sel.xpath('//ul/li')

for site in sites:
    title = sites.path('a/text()').extract()
    print(title)

将筛选后的数据存放到item里面去

最简单的工具是FixBox,他有四种形式方便导出
1)json
以json的方式导出到文件items.json

scrapy crawl dmoz -o items.json -t json

2)jsonlines
3)csv
4)xml



lxml

etree.HTML():把html的文本内容解析成html对象(会自动补全),同时也是XPath解析对象

 html = etree.HTML(response.content.decode())#把html的文本内容解析成html对象
#etree读取文件进行解析

etree.tostring(html).decode(‘utf-8’):将html对象解析成字符串类型 并设置解码方式

from lxml import etree
text = '''
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html">third item</a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a>
     </ul>
 </div>
'''
html = etree.HTML(text)
print(etree.tostring(html).decode('utf-8'))

xpath:对HTML文档进行搜索


https://blog.csdn.net/qq_25343557/article/details/81912992?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

html对象就是xpath解析对象

xpath常用规则(返回list)

/用于获取直接子节点,//用于获取子孙节点:

表达式	描述
nodename	选择这个节点名的所有子节点
/	从当前节点选择直接子节点
//	从当前节点选取子孙节点

.	选择当前节点
…	选取当前节点的父节点
@	选取属性

引入:from lxml import etree

例子:

/html/head/title:选取html文档中<head>标签内的<title>元素

/html/head/title/text():选择上面提到的<title>元素的文字

//td:选择所有的<td>元素

//div[@class="mine"]:选取所有具有class=“”mine“”属性的div元素

获取所有节点:

result = html.xpath('//*')
'//'表示获取当前节点子孙节点,'*'表示所有节点,'//*'表示获取当前节点下所有节点
for item in result:
    print(item)

获取所有特定节点,如获取所有的li节点。
result = html.xpath('//li')#将*改为li,表示只获取名称为li的子孙节点
#返回一个列表
for item in result:
    print(item)

获取所有某特定节点下的子节点(被父结点包围),如li结点下的a结点
result = html.xpath('//li/a')#//li选择所有的li节点,/a选择li节点下的直接子节点a
for item in result:
    print(item)

根据属性获取特定节点:

result = html.xpath('//li[@class="item-3"]')
#返回class属性为item-3的li结点(列表形式)

获取特定属性
html.xpath('//ul[@id="pins"]/li/a/@href') 
#获取id为pins的ul结点 下的子节点li 下的子节点 的href属性的值



异常处理

URLError:访问网页异常

import urllib.request as r
import urllib.error

req=r.Request("http://www/ooxx-fishc.com")

try:
    r.urlopen(req)
except urllib.error.URLError as e:
    print(e.reason)

HTTPError:状态码异常
http状态码大全

400-499:问题来自于客户端
500-599:服务器问题

except urllib.error.HPPTError as e:
 print(e.reason)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值