Python课程设计太平洋汽车网爬虫.zip


《Python程序语言基础》期末课程设计

(2020-2021学年第二学期)

学生姓名: 库洛

提交日期:2021年 7月2日

学 号         座位编号     
学 院    电子与信息学院    专业班级    信息工程5班
课程名称    Python程序语言基础    任课教师    田 翔
教师评语:
本论文成绩评定: 分
目 录

一、系统功能设计21、系统描述22、对象清单23、类设计2二、主要流程设计31、Scrapy框架构成:3(1)、调度器(Scheduler):4(2)、下载器(Downloader):4(3)、 爬虫(Spider):4(4)、 实体管道(Items Pipeline):4(5)、引擎(Scrapy Engine):4(6)、下载器中间件(Downloader Middlewares):4(7)、爬虫中间件(Spider Middlewares):4(8)、调度中间件(Scheduler Middewares):42、scrapy详细工作流程5三、前端界面设计6四、后台数据库设计6五、核心算法流程图7六、使用手册71、爬虫运行方法72、数据查看及处理8七、核心功能源代码101、tpy.py102、items.py123、pipelines.py13

太平洋汽车网评论爬虫

一、系统功能设计
1、系统描述
本爬虫基于scrapy框架,可以完成对太平洋汽车网用户评论的全自动爬取,包括两层循环的翻页,爬行逻辑为先翻页爬取某车型的所有评论,再翻页爬取其他车型评论,且根据网站总编码爬行,理论上可以爬取太平洋汽车网所有评论内容。

其中,使用User-Agent轮转,禁用cookies,降低被封几率,降低下载延时,提高下载速度,提升爬取效率。

爬取的评论信息内容包括车主昵称、发布时间、购买车型、裸车价格/万元,以及评论的具体分项,如优点、缺点、外观、内饰、空间、配置、动力、越野、油耗、舒适。前端用户通过Excel表格查看爬取内容,可按品牌、具体车型,价格区间等多种方式进行相关商品的搜索、筛选、查询、对比等。默认为总览模式,如需查看完整内容只需把自动换行打开即可。

2、对象清单
本爬虫由以下几个模块组成,功能设计如下:

tpy.py    爬虫总文件,决定爬虫运行逻辑
items.py    项目文件,编写爬虫的爬取项目
pipelines.py    管道文件,设计爬虫数据下载和储存
settings.py    设置文件,设置scrapy爬取参数
middlewares.py    下载中间件,主要用于设置UA轮转
run.py    启动爬虫,用于代替命令行方式启动
crawl.py    官方启动方式,主要用于封装
scrapy.cfg    scrapy启动必备组件
generate_cfg.py    用于运行时生成scrapy.cfg方便封装
mime.types    scrapy组件,用于封装
VERSION    scrapy组件,用于封装
3、类设计
tpy.py

class TpySpider(scrapy.Spider)    爬虫类,获取开始值和结束值用于限制爬行范围,设置start_urls确定爬虫起始爬取地址。
def parse(self, response)    提取response中特定字段信息,通过xpath按层查找所需信息。爬取翻页设计,包括大小两层循环,小翻页为同种型号汽车的多页评论爬取,大翻页为不同型号汽车的评论爬取。
items.py

class TpyspiderItem(scrapy.Item)    确定爬取每个内容的具体项目名称
pipelines.py

class TpyspiderPipeline(object)    爬取管道设计
def __init__(self)    创建CSV文件并输入第一行中文标题
def process_item(self, item, spider)    将爬取内容写入CSV文件
def close_spider(self, spider)    爬虫关闭函数,关闭时顺带关闭保存CSV文件,之后.csv转.xlsx文件并调整列宽直接覆盖
middlewares.py

class MyUserAgentMiddleware(UserAgentMiddleware)    设置User-Agent轮转
二、主要流程设计
1、Scrapy框架构成:

Scrapy框架主要由五大组件组成,它们分别是调度器(Scheduler)、下载器(Downloader)、爬虫(Spider)和实体管道(Items Pipeline)、引擎(Scrapy Engine)。此外还有各种中间件,如下载器中间件(Downloader Middlewares)、爬虫中间件(Spider Middlewares)、调度中间件(Scheduler Middewares),下面我们分别介绍各个组件的作用。

、调度器(Scheduler):
调度器,用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址用户可以自己的需求定制调度器。
、下载器(Downloader):
下载器,是所有组件中负担最大的,它用于高速地下载网络上的资源,并将网页内容返回给蜘蛛。Scrapy的下载器代码不会太复杂,但效率高,主要的原因是Scrapy下载器是建立在twisted这个高效的异步模型上的(其实整个框架都在建立在这个模型上的)。
、 爬虫(Spider):
爬虫,是用户最关心的部份。用户定制自己的爬虫(通过定制正则表达式等语法),用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。 用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。
、 实体管道(Items Pipeline):
实体管道,负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
、引擎(Scrapy Engine):
引擎是整个框架的核心.它用来控制调试器、下载器、爬虫,进行整个系统的数据流处理, 触发事务。实际上,引擎相当于计算机的CPU,它控制着整个流程。
、下载器中间件(Downloader Middlewares):
位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
、爬虫中间件(Spider Middlewares):
介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
、调度中间件(Scheduler Middewares):
介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。

2、scrapy详细工作流程

、首先Spiders(爬虫)将需要发送请求的url(requests)经ScrapyEngine(引擎)交给Scheduler(调度器)。
、Scheduler(排序,入队)处理后,经ScrapyEngine,DownloaderMiddlewares(可选,主要有User_Agent, Proxy代理)交给Downloader。
、Downloader向互联网发送请求,并接收下载响应(response)。将响应(response)经ScrapyEngine,SpiderMiddlewares(可选)交给Spiders。     
、Spiders处理response,提取数据并将数据经ScrapyEngine交给ItemPipeline保存(可以是本地,可以是数据库)。
、提取url重新经ScrapyEngine交给Scheduler进行下一个循环。直到无Url请求程序停止结束。


三、前端界面设计
用户操作前端界面为爬虫启动时的黑框界面和数据处理时的Excel界面,具体内容在使用手册中介绍。

四、后台数据库设计
爬取数据生成 缓存.csv文件,爬虫关闭时,.csv转.xlsx并调整列宽覆盖,生成 ^爬虫数据.xlsx文件(自动根据开始值和结束值命名)。

五、核心算法流程图


六、使用手册
1、爬虫运行方法

爬虫运行开始值与结束值范围大概在 6-30000 之间(前5个是空的,30000之后爬了4000个网页没有数据,可以认为之后的是空的,中间也有一大堆空的,遇到多半报404或503错误,已设置报错选项,忽略报错继续爬行),运行方法从以下任选一种即可。

1.1 双击封包之后生成的 .*.exe文件(推荐),填入开始值和结束值运行爬虫。

这个方法可以将 .*.exe文件 放到任何一台计算机上使用,而无需环境支持,运行时自动生成scrapy.cfg文件(scrapy框架运行所需)、缓存.csv文件,爬虫关闭时,.csv转.xlsx并调整列宽覆盖,生成 ^爬虫数据.xlsx文件(自动根据开始值和结束值命名)。

ps.如需多次使用爬虫,请在开始之前将缓存.csv删除,否则新数据会添加在旧数据后,最后全部写入 ^爬虫数据.xlsx文件

1.2 双击 crawl.py 或 run.py 以Python方式打开爬虫,填入开始值和结束值运行爬虫。

此方法需要Python环境,scrapy框架,以及所有爬虫里import的包的支持。

1.3 使用pycharm打开crawl.py 或 run.py,可以检查并补充缺失的环境变量,crawl.py 和 run.py实现的功能一致,不过方法不同:crawl.py是官方的scrapy启动方法,run.py实际上是命令行方法。

1.4 命令行方法:在爬虫目录打开cmd,输入命令 scrapy crawl tpy ,填入开始值和结束值运行爬虫。

此方法需要Python环境,scrapy框架,以及所有爬虫里import的包的支持。

运行截图如下:


2、数据查看及处理

打开^爬虫数据.xlsx文件,里面记录了爬取的评论信息,包括车主昵称、发布时间、购买车型、裸车价格/万元,以及评论的具体分项,如优点、缺点、外观、内饰、空间、配置、动力、越野、油耗、舒适。前端用户可按品牌、具体车型,价格区间等多种方式进行相关商品的搜索、筛选、查询、对比等。默认为总览模式,如需查看完整内容只需把自动换行打开即可。

运行截图:

筛选价格区间:

品牌筛选:

发布时间排序:

具体评论内容查看:

七、核心功能源代码
运行环境:win10-64位 编程语言: Python

编译器:Python 3.8(Python-3.9.4)

1、tpy.py

import scrapy

from scrapy.http import Request

from ..items import TpyspiderItem

class TpySpider(scrapy.Spider):

name = 'tpy'

allowed_domains = ['www.pcauto.com.cn']

handle_httpstatus_list = [404, 503]

page = 1

start = int(input("请输入开始值:"))

stop = int(input("请输入结束值:"))

offset = start

start_urls = ['https://price.pcauto.com.cn/comment/sg{}/t1/p1.html'.format(str(offset))]

print(start_urls)

def parse(self, response):

"""

@params:response,提取response中特定字段信息

"""

items = TpyspiderItem()

lists = response.xpath('//div[@class="litDy clearfix"]')

for i in lists:

items['cznc'] = i.xpath('.//div[@class="txBox"]/div[1]/p/a/text()').extract()

items['fbsj'] = i.xpath('.//div[@class="txBox"]/div[1]/span/a/text()').extract()

items['gmcx'] = i.xpath('.//div[@class="txBox"]/div[2]/a/text()').extract()

items['lcjg'] = i.xpath('.//div[@class="txBox"]/div[6]/i/text()').extract()

items['yd'] = i.xpath('.//div[@class="dianPing clearfix"]/div[1]/span/text()').extract()

items['qd'] = i.xpath('.//div[@class="dianPing clearfix"]/div[2]/span/text()').extract()

items['wg'] = i.xpath('.//div[@class="dianPing clearfix"]/div[3]/span/text()').extract()

items['ns'] = i.xpath('.//div[@class="dianPing clearfix"]/div[4]/span/text()').extract()

items['kj'] = i.xpath('.//div[@class="dianPing clearfix"]/div[5]/span/text()').extract()

items['pz'] = i.xpath('.//div[@class="dianPing clearfix"]/div[6]/span/text()').extract()

items['dl'] = i.xpath('.//div[@class="dianPing clearfix"]/div[7]/span/text()').extract()

items['yy'] = i.xpath('.//div[@class="dianPing clearfix"]/div[8]/span/text()').extract()

items['yh'] = i.xpath('.//div[@class="dianPing clearfix"]/div[9]/span/text()').extract()

items['ss'] = i.xpath('.//div[@class="dianPing clearfix"]/div[10]/span/text()').extract()

yield items

if self.offset < self.stop:

if response.xpath('//a[@class="next"]'):

# 小翻页,同种型号汽车的多页评论爬取

self.page += 1

url = 'https://price.pcauto.com.cn/comment/sg{}/t1/p{}.html'.format(str(self.offset), str(self.page))

print(url)

yield Request(url=url, callback=self.parse, dont_filter=True)

else:

# 大翻页,不同型号汽车的评论爬取

self.page = 1

self.offset += 1

url = 'https://price.pcauto.com.cn/comment/sg{}/t1/p1.html'.format(str(self.offset))

print(url)

yield Request(url=url, callback=self.parse, dont_filter=True)

# dont_filter=True,忽略allowed_domains的过滤

# 为了防止二次解析的域名被过滤掉,否则 DEBUG: Filtered offsite request to

2、items.py

import scrapy

class TpyspiderItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

# 车主昵称

cznc = scrapy.Field()

# 发布时间

fbsj = scrapy.Field()

# 购买车型

gmcx = scrapy.Field()

# 裸车价格/万元

lcjg = scrapy.Field()

# 优点

yd = scrapy.Field()

# 缺点

qd = scrapy.Field()

# 外观

wg = scrapy.Field()

# 内饰

ns = scrapy.Field()

# 空间

kj = scrapy.Field()

# 配置

pz = scrapy.Field()

# 动力

dl = scrapy.Field()

# 越野

yy = scrapy.Field()

# 油耗

yh = scrapy.Field()

# 舒适

ss = scrapy.Field()

3、pipelines.py

import csv

import os

import pandas as pd

from openpyxl import load_workbook

import tpyspider.spiders.tpy

class TpyspiderPipeline(object):

start = tpyspider.spiders.tpy.TpySpider.start

stop = tpyspider.spiders.tpy.TpySpider.stop

def __init__(self):

# csv文件的位置,无需事先创建

store_file = os.path.dirname(os.path.abspath("__file__")) + '/缓存.csv'

# store_file = os.path.dirname(__file__) + '/spiders/tpy.csv'

# 打开(创建)文件

self.file = open(store_file, 'a+', encoding="utf-8", newline='')

# csv写法

self.writer = csv.writer(self.file, dialect="excel")

self.header = ['车主昵称', '发布时间', '购买车型', '裸车价格/万元', '优点', '缺点', '外观', '内饰', '空间', '配置', '动力', '越野', '油耗', '舒适']

self.a = ['cznc', 'fbsj', 'gmcx', 'lcjg', 'yd', 'qd', 'wg', 'ns', 'kj', 'pz', 'dl', 'yy', 'yh', 'ss']

self.csvWrite = csv.DictWriter(self.file, fieldnames=self.header)

self.csvWrite.writeheader()

def process_item(self, item, spider):

temp = {}

self.csvWrite = csv.DictWriter(self.file, fieldnames=self.a)

for column in self.a:

temp[column] = ''.join(item[column])

self.csvWrite.writerow(temp)

return item

def close_spider(self, spider):

name = "爬虫数据" + str(self.start) + "-" + str(self.stop)

# 关闭爬虫时顺便将文件保存退出

self.file.close()

csv1 = pd.read_csv(os.path.dirname(os.path.abspath("__file__")) + '/缓存.csv', encoding='utf-8')

csv1.to_excel(os.path.dirname(os.path.abspath("__file__")) + '/' + name + '.xlsx', sheet_name='data', index=False)

# index=False,.csv转.xlsx时去掉自动序号

# 修改列宽

# path = 'tpy.xlsx'

# 上一行可以在pycharm内运行,不过直接运行run.py无法找到tpy.xlsx,故改成下一行完整写法

# path = os.path.dirname(__file__) + '/spiders/tpy.xlsx'

path = os.path.dirname(os.path.abspath("__file__")) + '/' + name + '.xlsx'

wb = load_workbook(path)

ws = wb.active

ws.column_dimensions['A'].width = 25

ws.column_dimensions['B'].width = 11

ws.column_dimensions['C'].width = 55

ws.column_dimensions['D'].width = 15

for i in range(5, 15):

ws.column_dimensions[chr(64 + i)].width = 50 # A是65

wb.save(name + '.xlsx')

# 修改列宽后直接覆盖
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/m0_66999594/article/details/139582246

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值