利用爬虫技术自动化采集汽车之家的车型参数数据

{亿牛云}.png

导语

汽车之家是一个专业的汽车网站,提供了丰富的汽车信息,包括车型参数、图片、视频、评测、报价等。如果我们想要获取这些信息,我们可以通过浏览器手动访问网站,或者利用爬虫技术自动化采集数据。本文将介绍如何使用Python编写一个简单的爬虫程序,实现对汽车之家的车型参数数据的自动化采集,并使用亿牛云爬虫代理服务来提高爬虫的稳定性和效率。

概述

爬虫技术是一种通过编程模拟浏览器访问网页,解析网页内容,提取所需数据的技术。爬虫程序通常需要完成以下几个步骤:

  • 发送HTTP请求,获取网页源代码
  • 解析网页源代码,提取所需数据
  • 存储或处理提取的数据

在实际的爬虫开发中,我们还需要考虑一些其他的问题,例如:

  • 如何避免被网站反爬机制识别和封禁
  • 如何提高爬虫的速度和效率
  • 如何处理异常和错误

为了解决这些问题,我们可以使用一些工具和服务来辅助我们的爬虫开发,例如:

  • 使用requests库来发送HTTP请求,简化网络编程
  • 使用BeautifulSoup库或者XPath语法来解析网页源代码,方便数据提取
  • 使用pandas库或者csv模块来存储或处理提取的数据,支持多种数据格式
  • 使用亿牛云爬虫代理服务来隐藏真实IP地址,防止被网站封禁
  • 使用多线程或者协程来并发发送HTTP请求,提高爬虫的速度和效率
  • 使用try-except语句或者logging模块来处理异常和错误,增加爬虫的稳定性和可维护性

正文

下面我们将使用Python编写一个简单的爬虫程序,实现对汽车之家的车型参数数据的自动化采集。我们以"奥迪A4L"为例,获取其所有在售车型的基本参数、动力参数、底盘转向参数、安全装备参数和外部配置参数。

1. 导入所需库和模块

首先,我们需要导入以下几个库和模块:

# 导入requests库,用于发送HTTP请求
import requests# 导入BeautifulSoup库,用于解析网页源代码
from bs4 import BeautifulSoup# 导入pandas库,用于存储或处理提取的数据
import pandas as pd# 导入time模块,用于控制爬虫速度
import time# 导入random模块,用于生成随机数
import random# 导入threading模块,用于实现多线程爬虫
import threading# 导入queue模块,用于实现线程间通信
import queue# 导入logging模块,用于记录日志信息
import logging

2. 定义全局变量和常量

接下来,我们需要定义一些全局变量和常量,用于存储或控制爬虫程序的运行状态:

# 定义奥迪A4L的车型参数页面的URL
URL = 'https://www.autohome.com.cn/3170/#levelsource=000000000_0&pvareaid=101594'# 定义亿牛云爬虫代理的域名、端口、用户名、密码
PROXY_HOST = 'www.16yun.cn'
PROXY_PORT = '8020'
PROXY_USER = '16YUN'
PROXY_PASS = '16IP'# 定义爬虫代理的HTTP头部
PROXY_HEADERS = {'Proxy-Authorization': 'Basic ' + base64.b64encode((PROXY_USER + ':' + PROXY_PASS).encode()).decode()
}# 定义爬虫请求的HTTP头部UserAgent
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}# 定义爬虫请求的超时时间(秒)
TIMEOUT = 10# 定义爬虫请求的重试次数
RETRY = 3# 定义爬虫请求的最小间隔时间(秒)
MIN_DELAY = 1# 定义爬虫请求的最大间隔时间(秒)
MAX_DELAY = 3# 定义爬虫线程的数量
THREADS = 10# 定义车型参数数据的列名
COLUMNS = ['车型', '基本参数', '动力参数', '底盘转向参数', '安全装备参数', '外部配置参数']# 定义车型参数数据的空列表,用于存储提取的数据
DATA = []# 定义车型URL的队列,用于实现线程间通信
QUEUE = queue.Queue()# 定义日志格式和级别
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)

3. 定义发送HTTP请求的函数

然后,我们需要定义一个函数,用于发送HTTP请求,获取网页源代码:

def get_html(url):# 初始化重试次数retry = RETRY# 循环发送HTTP请求,直到成功或达到重试次数上限while retry > 0:try:# 使用requests库发送HTTP请求,设置代理和超时时间response = requests.get(url, headers=HEADERS, proxies={'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'}, timeout=TIMEOUT)# 判断HTTP响应状态码是否为200,即成功if response.status_code == 200:# 返回网页源代码return response.text# 否则,记录错误信息,并减少重试次数else:logging.error(f'请求失败,状态码:{response.status_code},URL:{url}')retry -= 1# 捕获异常,并记录错误信息,并减少重试次数except Exception as e:logging.error(f'请求异常,异常信息:{e},URL:{url}')retry -= 1# 如果重试次数为0,说明请求失败,返回空值if retry == 0:logging.error(f'请求失败,重试次数用尽,URL:{url}')return None

4. 定义解析网页源代码的函数

接着,我们需要定义一个函数,用于解析网页源代码,提取所需数据:

def parse_html(html):# 使用BeautifulSoup库解析网页源代码,指定解析器为lxmlsoup = BeautifulSoup(html, 'lxml')# 使用XPath语法提取车型名称car_name = soup.select_one('//div[@class="subnav-title-name"]/a/text()')# 使用XPath语法提取车型参数表格car_table = soup.select_one('//div[@id="config_data"]/div/table')# 判断车型名称和车型参数表格是否存在if car_name and car_table:# 初始化车型参数数据的字典,用于存储提取的数据car_data = {}# 将车型名称添加到车型参数数据的字典中,作为第一个键值对# 使用XPath语法提取车型参数表格的所有行car_rows = car_table.select('//tr')# 遍历车型参数表格的所有行for car_row in car_rows:# 使用XPath语法提取每一行的第一个单元格,即参数类别car_category = car_row.select_one('//th/text()')# 使用XPath语法提取每一行的第二个单元格,即参数值car_value = car_row.select_one('//td/div/text()')# 判断参数类别和参数值是否存在if car_category and car_value:# 将参数类别和参数值添加到车型参数数据的字典中,作为键值对car_data[car_category] = car_value# 返回车型参数数据的字典return car_data# 否则,记录错误信息,并返回空值else:logging.error('解析失败,无法提取车型名称或车型参数表格')return None

5. 定义存储或处理提取的数据的函数

然后,我们需要定义一个函数,用于存储或处理提取的数据:

def save_data(data):# 判断数据是否存在if data:# 将数据添加到车型参数数据的空列表中DATA.append(data)# 记录信息,显示数据已保存logging.info(f'数据已保存,车型:{data["车型"]}')# 否则,记录错误信息,显示数据为空else:logging.error('数据为空,无法保存')

6. 定义爬虫线程的类

接着,我们需要定义一个类,用于实现爬虫线程的功能:

class SpiderThread(threading.Thread):# 重写初始化方法,传入线程名称和队列对象def __init__(self, name, queue):# 调用父类的初始化方法super().__init__()# 设置线程名称self.name = name# 设置队列对象self.queue = queue# 重写运行方法,实现爬虫逻辑def run(self):# 记录信息,显示线程开始运行logging.info(f'线程{self.name}开始运行')# 循环从队列中获取车型URL,直到队列为空while not self.queue.empty():# 从队列中获取车型URL,并移除该元素url = self.queue.get()# 记录信息,显示正在处理该URLlogging.info(f'线程{self.name}正在处理{url}')# 调用发送HTTP请求的函数,获取网页源代码html = get_html(url)# 判断网页源代码是否存在if html:# 调用解析网页源代码的函数,提取所需数据data = parse_html(html)# 调用存储或处理提取的数据的函数,保存或处理数据save_data(data)# 否则,记录错误信息,显示网页源代码为空else:logging.error(f'网页源代码为空,无法处理{url}')# 生成一个随机数,作为爬虫请求的间隔时间delay = random.randint(MIN_DELAY, MAX_DELAY)# 记录信息,显示爬虫请求的间隔时间logging.info(f'线程{self.name}等待{delay}秒')# 使用time模块暂停爬虫请求的间隔时间time.sleep(delay)# 记录信息,显示线程结束运行logging.info(f'线程{self.name}结束运行')

7. 定义主函数

最后,我们需要定义一个主函数,用于启动爬虫程序:

def main():# 记录信息,显示爬虫程序开始运行logging.info('爬虫程序开始运行')# 调用发送HTTP请求的函数,获取车型参数页面的网页源代码html = get_html(URL)# 判断网页源代码是否存在if html:# 使用BeautifulSoup库解析网页源代码,指定解析器为lxmlsoup = BeautifulSoup(html, 'lxml')# 使用XPath语法提取所有在售车型的URL列表car_urls = soup.select('//div[@id="config_data"]/div/div/ul/li/a/@href')# 判断车型URL列表是否存在if car_urls:# 遍历车型URL列表for car_url in car_urls:# 将车型URL添加到车型URL的队列中QUEUE.put(car_url)# 初始化一个空列表,用于存储爬虫线程对象threads = []# 遍历爬虫线程的数量范围for i in range(THREADS):# 创建一个爬虫线程对象,并传入线程名称和队列对象thread = SpiderThread(f'线程{i+1}', QUEUE)# 将爬虫线程对象添加到爬虫线程对象的空列表中threads.append(thread)# 遍历爬虫线程对象的空列表for thread in threads:# 启动爬虫线程thread.start()# 遍历爬虫线程对象的空列表for thread in threads:# 等待爬虫线程结束thread.join()# 记录信息,显示所有爬虫线程已结束logging.info('所有爬虫线程已结束')# 否则,记录错误信息,显示车型URL列表为空else:logging.error('车型URL列表为空,无法继续爬取')# 否则,记录错误信息,显示网页源代码为空else:logging.error('网页源代码为空,无法继续爬取')# 判断车型参数数据的空列表是否存在if DATA:# 使用pandas库创建一个数据框对象,传入车型参数数据的空列表和列名df = pd.DataFrame(DATA, columns=COLUMNS)# 使用pandas库将数据框对象保存为CSV文件,指定文件名和编码格式df.to_csv('car_data.csv', encoding='utf-8-sig', index=False)# 记录信息,显示数据已导出为CSV文件logging.info('数据已导出为CSV文件')# 否则,记录错误信息,显示数据为空else:logging.error('数据为空,无法导出')# 记录信息,显示爬虫程序结束运行logging.info('爬虫程序结束运行')

结语

本文介绍了如何使用Python编写一个简单的爬虫程序,实现对汽车之家的车型参数数据的自动化采集,并使用亿牛云爬虫代理服务来提高爬虫的稳定性和效率。本文只是一个简单的示例,实际的爬虫开发可能需要更多的技巧和知识。希望本文能够对你有所帮助和启发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141067.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

使用Python做一个微信机器人

介绍 简介 该程序将微信的内部功能提取出来,然后在程序里加载Python,接着将这些功能导出成库函数,就可以在Python里使用这些函数 程序启动的时候会执行py_code目录下的main.py,类似于你在命令行使用python main.py。 现在会以…

011_第一代软件开发(三)

第一代软件开发(三) 文章目录 第一代软件开发(三)项目介绍带下知识点系统日志滤波器陷波滤波器带通滤波器 打印初始化调用打印机打印文件保存到PDF 总结一下 关键字: Qt、 Qml、 日志、 打印、 滤波器 项目介绍 欢迎来到我们的 QML & C 项目!这…

rom修改----安卓系列机型如何内置app 如何选择so文件内置

系统内置app的需求 在与各工作室对接中操作单中,很多需要内置客户特定的有些app到系统里,这样方便客户刷入固件后直接调用。例如内置apk 去开机引导 去usb调试 默认开启usb安全设置等等。那么很多app内置有不同的反应。有的可以直接内置。有的需要加so…

【三、centOS安装后的基本配置】

Centos的ip地址设定,cmd查看 Windows: ipconfig 再到windows电脑的网络共享中心查看 设置虚拟机的IPv4,锁定本地电脑的ip地址和网关 再重启虚拟机机器,vi /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_MET…

JavaScript学习笔记05

JavaScript笔记05 操作 BOM 对象(重点) 什么是 BOM BOM(Browser Object Model)是指浏览器对象模型,是用于描述这种对象与对象之间层次关系的模型。浏览器对象模型(BOM)提供了独立于内容的、可…

设计模式再探——原型模式

目录 一、背景介绍二、思路&方案三、过程1.原型模式简介2.原型模式的类图3.原型模式代码4.原型模式深度剖析5.原型模式与spring 四、总结五、升华 一、背景介绍 最近在做业务实现的时候,为了通过提升机器来降低开发人员的难度和要求,于是在架构设计…

用Redis做数据排名

1.背景 用Redis做数据缓存用的比较多,大家都能熟练使用String和Hash结构去存储数据,今天讲下如何使用ZSet来做数据排名。 假设场景是需要按天存储全国城市的得分数据,可以查询前十名的城市排名。 这个case可以使用传统关系型数据库做…

【lesson7】git的介绍及使用

文章目录 什么是gitgit的历史git使用在gitee上创建仓库git clone HTTPS地址git add .git add 文件名git commit “日志”git pushgit loggit rm 文件名git statusgit pull 什么是git git是版本控制器,那么什么是版本控制器呢? 下面讲个故事为大家讲解一…

AI AIgents时代 - (三.) AutoGPT和AgentGPT

前两篇讲解了Agent的原理和组件,这节我将给大家介绍两个agent项目,给出它们的工作原理和区别,并教大家亲手尝试使用 Agents🎉 🟢 AutoGPT🤖️ 我们的老朋友,之前文章也专门写过。AutoGPT 是一…

iphone的safari浏览器实现全屏的pwa模式,并修改顶部状态栏背景颜色

要想修改顶部背景颜色&#xff0c;需要用到这个属性&#xff1a;content就是你要设置的颜色 <!-- 状态栏的背景色 --><meta name"theme-color" content"#f8f8f8" /> 然后再加上下面的设置&#xff1a; <!-- 网站开启对 web app 程序的支持…

【数据结构】C++实现哈希表

闭散列哈希表 哈希表的结构 在闭散列的哈希表中&#xff0c;哈希表每个位置除了存储所给数据之外&#xff0c;还应该存储该位置当前的状态&#xff0c;哈希表中每个位置的可能状态如下&#xff1a; EMPTY&#xff08;无数据的空位置&#xff09;。EXIST&#xff08;已存储数…

Qt创建线程(线程池)

1.线程池可以创建线程统一的管理线程&#xff08;统一创建、释放线程&#xff09; 2.使用线程池方法实现点击开始按钮生成10000个随机数&#xff0c;然后分别使用冒泡排序和快速排序排序这10000个随机数&#xff0c;最后在窗口显示排序后的数字&#xff1a; mainwindow.h文件…

FPGA的DQPSK调制解调Verilog

名称&#xff1a;DQPSK调制解调 软件&#xff1a;Quartus 语言&#xff1a;Verilog 要求&#xff1a; 使用Verilog语言进行DQPSK调制和解调&#xff0c;并进行仿真 代码下载&#xff1a;DQPSK调制解调verilog&#xff0c;quartus_Verilog/VHDL资源下载 代码网&#xff1a;h…

Vector Art - 矢量艺术

什么是矢量艺术&#xff1f; 矢量图形允许创意人员构建高质量的艺术作品&#xff0c;具有干净的线条和形状&#xff0c;可以缩放到任何大小。探索这种文件格式如何为各种规模的项目提供创造性的机会。 什么是矢量艺术作品? 矢量艺术是由矢量图形组成的艺术。这些图形是基于…

【音视频】ffplay源码解析-PacketQueue队列

包队列架构位置 对应结构体源码 MyAVPacketList typedef struct MyAVPacketList {AVPacket pkt; //解封装后的数据struct MyAVPacketList *next; //下一个节点int serial; //播放序列 } MyAVPacketList;PacketQueue typedef struct PacketQueue {MyAVPacketList …

快递发货小程序商城的效果是什么

商家搭建小程序商城后&#xff0c;客户交易可以通过到店自提、同城配送、快递发货的方式满足不同场景不同客户购物。 本地客户难以拓展&#xff0c;三公里范围内流量有限&#xff0c;外地无疑是商家拓展市场、客户的绝佳选择&#xff0c;传统电话、微信联系难以信任及选择&…

问题:conda删除虚拟环境,报错no package names supplied

用conda 用 conda remove -n ScratchDet_20200114 删除虚拟 环境ScratchDet_20200114时报错 conda remove -n ScratchDet_20200114CondaValueError: no package names supplied,try "conda remove -h" for more details 解决方法&#xff0c;用下面的命令 conda env…

FPGA的BPSK调制verilog

名称&#xff1a;BPSK调制verilog 软件&#xff1a;Quartus 语言&#xff1a;Verilog 要求&#xff1a; 一、设计说明 BPSK调制广泛应用于卫星通信、移动通信等领域。本题目要求设计一个基于直接数字频率合成技术的BPSK调制器&#xff0c;实现对输入周期数字比特流的BPSK调…

LeetCode 周赛上分之旅 #47 前后缀分解结合单调栈的贡献问题

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

【深度学习实验】前馈神经网络(一):使用PyTorch构建神经网络的基本步骤

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 定义x,w,b 2. 计算净活性值z 3. 实例化线性层并进行前向传播 4. 打印结果 5. 代码整合 一、实验介绍 本实验使用了PyTorch库来构建和操作神经网络模型&#xff0c;主要是关…