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

{亿牛云}.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.mzph.cn/news/81527.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB中findpeaks函数用法

目录 语法 说明 示例 在MATLAB中,findpeaks函数用于查找信号中的峰值(peaks)。以下是findpeaks函数的基本语法、说明以及示例: 语法 [pks,locs] findpeaks(x) [pks,locs] findpeaks(x, Name, Value)说明 参数说明 x&…

勒索病毒最新变种.halo勒索病毒来袭,如何恢复受感染的数据?

摘要: .halo勒索病毒已成为数字世界中的威胁,通过高级加密技术将文件锁定,并要求支付赎金。本文91数据恢复将深入介绍.halo勒索病毒的工作原理,提供解锁被感染文件的方法,以及探讨如何有效预防这一威胁。如果您正在经…

87 # express 应用和创建应用的分离

创建应用的过程和应用本身要进行分离。路由和创建应用的过程也做一个分离。 下面实现创建应用的过程和应用本身要进行分离: express.js const Application require("./application");function createApplication() {// 通过类来实现分离操作return ne…

unity UDP 通信

客户端 接收端 : using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI;public cla…

常见音视频、流媒体开源编解码库及官网(四十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

Unity中Shader抓取屏幕并实现扭曲效果(优化)

文章目录 前言一、在之前顶点着色器的输入中,放弃了使用结构体传入,而是直接从应用程序阶段传入参数,这样写的话,对于程序来说,不方便扩张,所以需要对其进行修改实现1、定义结构体用于传入顶点坐标系2、因为…

开始撸 Android 源码

启动找工作模式,发现无比困难。搁在往日,大龄程序员找工作都是一件困难的事情,加上今年形势很差,更是难上加难。关键是我这十几年来主攻的浏览器内核方向,需求量更是几乎为零。在 BOSS 直聘上以 Chromium 为关键词&…

华为云云耀云服务器L实例评测|Git 私服搭建指南

前言 本文为华为云云耀云服务器L实例测评文章,测评内容是 云耀云服务器L实例 Git 私有服务器搭建指南 系统配置:2核2G 3M Ubuntu 20.04 我们平时在使用代码托管服务的时候,可能某些代码托管平台对成员有限制,或是由于内容原因会对…

教你如何清理 Docker 存储驱动的磁盘占用空间

Author:rab 有时候你会发现,你的 Docker 业务容器虽然做了数据持久化,且数据持久化的磁盘空间占用并不大,但是 Docker 的 Overlay2 目录占用却很大。我们知道 Overlay2 是 Docker 的存储驱动,也是 Docker 默认的存储驱…

Vue Router最佳实践,以确保你的Vue.js应用的路由管理清晰、可维护和高效

文章目录 路由结构设计命名路由动态路由参数导航守卫命名视图 (Named Views)懒加载路由错误处理 ✍创作者:全栈弄潮儿 🏡 个人主页: 全栈弄潮儿的个人主页 🏙️ 个人社区,欢迎你的加入:全栈弄潮儿的个人社区…

3D动画制作和渲染需要什么样的硬件规格?

动画是艺术与技术的令人兴奋的融合,为无限的创造力提供了广阔的画布。为了将创意愿景变为现实,动画师需要适合其工艺的强大计算资源。每个动画项目都有不同的硬件需求,无论是制作简单的 2D 动画还是构建复杂的 3D 世界。因此,有抱…

企业架构LNMP学习笔记51

企业案例使用: 主从模式: 缓存集群结构示意图: 去实现Redis的业务分离: 读的请求分配到从服务器上,写的请求分配到主服务器上。 Redis是没有中间件来进行分离的。 是通过业务代码直接来进行读写分离。 准备两台虚…

十七、Webpack搭建本地服务器

一、为什么要搭建本地服务器? 目前我们开发的代码,为了运行需要有两个操作: 操作一:npm run build,编译相关的代码;操作二:通过live server或者直接通过浏览器,打开index.html代码…

Datastage部署与使用

Datastage部署与使用 - 码农教程 https://www.cnblogs.com/lanston/category/739553.html Streamsets定时拉取接口数据同步到HBase集群_streamsets api_webmote的博客-CSDN博客 【SDC】StreamSets实战之路-28-实战篇- 使用StreamSets实时采集指定数据目录文件并写入库Kudu_菜…

【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式

目录 1、函数指针数组 1.1、函数指针数组是什么? 1.2、函数指针数组的用途:转移表 2、扩展:指向函数指针的数组的指针 3、回调函数 3.1、回调函数介绍 3.2、回调函数的案例:qsort函数 3.2.1、回顾冒泡排序 3.2.1、什么是qso…

构建工具Webpack简介

一、构建工具 当我们习惯了Node中使用ES模块化编写代码以后,用原生的HTML、CSS、JS这些东西会感觉到各种不便。比如:不能放心的使用模块化规范(浏览器兼容性问题)、即使可以使用模块化规范也会面临模块过多时的加载问题。 这时候…

基于uniapp开发 软盒APP系统源码 软件库系统源码 全开源

软盒APP前端-基于uniapp,一个开源的软件库系统 前端开源地址:软盒APP前端-基于uniapp: 软盒APP前端-基于uniapp (gitee.com) 更新说明 更新日期:2023.07.24 v1.0.8.23724 1.修复部分接口 2.删除根据标签获取软件列表接口,整合…

JDBC和DBUtils框架的使用

课程目录 一、JDBC概述 二、JDBC基本操作 三、使用PreparedStatement处理CRUD 四、数据库连接池 五、Apache的DBUtils 六、Dao类 一、JDBC概述 1. 为什么需要JDBC 没有JDBC时: 有了JDBC后: 2. JDBC概述 JDBC:Java Database Conn…

东芝电视Z750的音画效果好吗?调校的够真实吗?

精准匹配声音与画面,呈现“音画合一”的影院级视听盛宴,东芝电视Z750真的很不错,东芝电视拥有70余年的原色调校技术,色彩看起来细腻且舒服,饱和度和景深等都处理的很恰当,而且还有火箭炮音响系统,也是经过日本专业调校的,针对不同家居场景,都有不同的声音处理方案,让我们听到的…

竞赛选题 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的人脸表情识别 该项目较…