爬虫之牛刀小试(十):爬取某宝手机商品的销量,价格和店铺

首先淘宝需要登录,这一点如果用selenium如何解决,只能手动登录?如果不用selenium,用cookies登录也可。但是验证码又是一个问题,现在的验证码五花八门,难以处理。

我们回到正题,假设你已经登录上淘宝了,接着我们需要找到输入框和搜索按钮,输入“手机”,点击搜索即可,如何找到对应的元素呢?
在这里插入图片描述
接着来到搜索得到的页面,首先找到父类容器的位置。


items = doc('div.PageContent--contentWrap--mep7AEm > div.LeftLay--leftWrap--xBQipVc > div.LeftLay--leftContent--AMmPNfB > div.Content--content--sgSCZ12 > div > div').items()

这行代码是使用Python的pyquery库来解析HTML并提取特定元素。代码是在doc(一个pyquery对象)中查找符合特定CSS选择器的元素。
这个CSS选择器匹配一个具有特定类名的div元素,该元素是另一个具有特定类名的div元素的直接子元素,以此类推。>符号表示“直接子元素”。
.items()方法是获取所有匹配的元素,并返回一个生成器,可以用于迭代每个匹配的元素。
在这里插入图片描述
接着运用找输入框和搜索按钮的方法找到你想要爬取内容的位置,下面展示其中一个的例子
在这里插入图片描述


title = item.find('.Title--title--jCOPvpf span').text()

这行代码是使用Python的BeautifulSoup库来解析HTML并提取特定元素的文本内容。
item.find(‘.Title–title–jCOPvpf span’)是在item(一个BeautifulSoup对象)中查找具有类名Title–title–jCOPvpf的元素,并且这个元素下的span子元素。

接着找到下一页的按钮,完成翻页的操作!
在这里插入图片描述
最后创建数据库,将数据插入即可。


# 删除同名的旧表
drop_table_sql = "DROP TABLE IF EXISTS {}".format(MYSQL_TABLE)
cursor.execute(drop_table_sql)# 创建新表的SQL语句
create_table_sql = """
CREATE TABLE {} (price VARCHAR(255),deal VARCHAR(255),title VARCHAR(255),shop VARCHAR(255),location VARCHAR(255),postFree VARCHAR(255)
)
""".format(MYSQL_TABLE)# 执行SQL语句
cursor.execute(create_table_sql)

最后的结果如下(使用Navicat Premium可视化):
在这里插入图片描述
这次共爬取4800件商品。

完整代码如下所示:


import pymysql
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import time
import random# 要搜索的商品的关键词
KEYWORD = '手机'
# 数据库中要插入的表
MYSQL_TABLE = 'phone'# MySQL 数据库连接配置,根据自己的本地数据库修改
db_config = {'host': 'localhost','port': 3306,'user': 'root','password': '123456','database': 'myh','charset': 'utf8mb4',
}# 创建 MySQL 连接对象
conn = pymysql.connect(**db_config)
cursor = conn.cursor()# 删除同名的旧表(如果存在)
drop_table_sql = "DROP TABLE IF EXISTS {}".format(MYSQL_TABLE)
cursor.execute(drop_table_sql)# 创建新表的SQL语句
create_table_sql = """
CREATE TABLE {} (price VARCHAR(255),deal VARCHAR(255),title VARCHAR(255),shop VARCHAR(255),location VARCHAR(255),postFree VARCHAR(255)
)
""".format(MYSQL_TABLE)# 执行SQL语句
cursor.execute(create_table_sql)# 提交事务
conn.commit()options = webdriver.ChromeOptions()
# 关闭自动测试状态显示 // 会导致浏览器报:请停用开发者模式
options.add_experimental_option("excludeSwitches", ['enable-automation'])# 把chrome设为selenium驱动的浏览器代理;
driver = webdriver.Chrome(options=options)
# 窗口最大化
driver.maximize_window()# wait是Selenium中的一个等待类,用于在特定条件满足之前等待一定的时间(这里是15秒)。
# 如果一直到等待时间都没满足则会捕获TimeoutException异常
wait = WebDriverWait(driver, 15)# 打开页面后会强制停止10秒,请在此时手动扫码登陆
def search_goods(start_page, total_pages):print('正在搜索: ')try:driver.get('https://www.taobao.com')# 强制停止10秒,请在此时手动扫码登陆time.sleep(10)driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",{"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})# 找到搜索输入框input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))# 找到“搜索”按钮submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))input.send_keys(KEYWORD)submit.click()# 搜索商品后会再强制停止10秒,如有滑块请手动操作time.sleep(10)# 如果不是从第一页开始爬取,就滑动到底部输入页面然后跳转if start_page != 1 :# 滑动到页面底端driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")# 滑动到底部后停留1-3srandom_sleep(1, 3)# 找到输入页面的表单pageInput = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/span[3]/input')))pageInput.send_keys(start_page)# 找到页面跳转的确定按钮,并且点击admit = wait.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/button[3]')))admit.click()get_goods()for i in range(start_page + 1, start_page + total_pages):page_turning(i)except TimeoutException:print("search_goods: error")return search_goods()
# 进行翻页处理
def page_turning(page_number):print('正在翻页: ', page_number)try:# 找到下一页的按钮submit = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/button[2]')))submit.click()# 判断页数是否相等wait.until(EC.text_to_be_present_in_element((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/span/em'), str(page_number)))get_goods()except TimeoutException:page_turning(page_number)
#获取每一页的商品信息;
def get_goods():# 获取商品前固定等待2-4秒random_sleep(2, 4)html = driver.page_sourcedoc = pq(html)# 提取所有商品的共同父元素的类选择器items = doc('div.PageContent--contentWrap--mep7AEm > div.LeftLay--leftWrap--xBQipVc > div.LeftLay--leftContent--AMmPNfB > div.Content--content--sgSCZ12 > div > div').items()for item in items:# 定位商品标题title = item.find('.Title--title--jCOPvpf span').text()# 定位价格price_int = item.find('.Price--priceInt--ZlsSi_M').text()price_float = item.find('.Price--priceFloat--h2RR0RK').text()if price_int and price_float:price = float(f"{price_int}{price_float}")else:price = 0.0# 定位交易量deal = item.find('.Price--realSales--FhTZc7U').text()# 定位所在地信息location = item.find('.Price--procity--_7Vt3mX').text()# 定位店名shop = item.find('.ShopInfo--TextAndPic--yH0AZfx a').text()# 定位包邮的位置postText = item.find('.SalesPoint--subIconWrapper--s6vanNY span').text()result = 1 if "包邮" in postText else 0# 构建商品信息字典product = {'title': title,'price': price,'deal': deal,'location': location,'shop': shop,'isPostFree': result}save_to_mysql(product)
# 在 save_to_mysql 函数中保存数据到 MySQL
def save_to_mysql(result):try:sql = "INSERT INTO {} (price, deal, title, shop, location, postFree) VALUES (%s, %s, %s, %s, %s, %s)".format(MYSQL_TABLE)print("sql语句为:  "  + sql)cursor.execute(sql, (result['price'], result['deal'], result['title'], result['shop'], result['location'], result['isPostFree']))conn.commit()print('存储到MySQL成功: ', result)except Exception as e:print('存储到MYsql出错: ', result, e)
# 强制等待的方法,在timeS到timeE的时间之间随机等待
def random_sleep(timeS, timeE):# 生成一个S到E之间的随机等待时间random_sleep_time = random.uniform(timeS, timeE)time.sleep(random_sleep_time)
# 在 main 函数开始时连接数据库
def main():try:pageStart = int(input("输入您想开始爬取的页面数: "))pageAll = int(input("输入您想爬取的总页面数: "))search_goods(pageStart, pageAll)except Exception as e:print('main函数报错: ', e)finally:cursor.close()conn.close()#启动爬虫
if __name__ == '__main__':main()

请大家关注一下我的公众号。
在这里插入图片描述

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

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

相关文章

计算机设计大赛 深度学习YOLO图像视频足球和人体检测 - python opencv

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络4 Yolov5算法5 数据集6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习YOLO图像视频足球和人体检测 该项目较为新颖,适合作为竞赛课题方向,学长非…

一览大模型长文本能力

前言 如今的大模型被应用在各个场景,其中有些场景则需要模型能够支持处理较长文本的能力(比如8k甚至更长),其中已经有很多开源或者闭源模型具备该能力比如GPT4、Baichuan2-192K等等。 那关于LLM的长文本能力,目前业界通常都是怎么做的&…

2024年腾讯云4核8G12M服务器性能测评,适合哪些使用场景?

腾讯云4核8G服务器适合做什么?搭建网站博客、企业官网、小程序、小游戏后端服务器、电商应用、云盘和图床等均可以,腾讯云4核8G服务器可以选择轻量应用服务器4核8G12M或云服务器CVM,轻量服务器和标准型CVM服务器性能是差不多的,轻…

阿里云BGP多线精品EIP香港CN2线路低时延,价格贵

阿里云香港等地域服务器的网络线路类型可以选择BGP(多线)和 BGP(多线)精品,普通的BGP多线和精品有什么区别?BGP(多线)适用于香港本地、香港和海外之间的互联网访问。使用BGP&#xf…

【实战】二、Jest难点进阶(一) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(五)

文章目录 一、Jest 前端自动化测试框架基础入门二、Jest难点进阶1.snapshot 快照测试 学习内容来源:Jest入门到TDD/BDD双实战_前端要学的测试课 相对原教程,我在学习开始时(2023.08)采用的是当前最新版本: 项版本babe…

jmeter遇到连接数据库的问题

jmeter连接mysql或者oracle简单,但是连接过inceptor吗? 上货 1、下载驱动inceptor 5.1.2.jar包 2、在添加驱动那里导入 3、在JBC request中的写法 PS:没什么可说的

【C++】类和对象(五)友元、内部类、匿名对象

前言:前面我们说到类和对象是一个十分漫长的荆棘地,今天我们将走到终点,也就是说我们对于C算是正式的入门了。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C学习 &…

嵌入式中全面解析 SPI 通信协议方法

SPI 的英文全称为 Serial Peripheral Interface,顾名思义为串行外设接口。SPI 是一种同步串行通信接口规范,主要应用于嵌入式系统中的短距离通信。该接口由摩托罗拉在20世纪80年代中期开发,后发展成了行业规范。 SPI 是一种高速的、全双工的…

算法沉淀——优先级队列(堆)(leetcode真题剖析)

算法沉淀——优先级队列 01.最后一块石头的重量02.数据流中的第 K 大元素03.前K个高频单词04.数据流的中位数 优先队列(Priority Queue)是一种抽象数据类型,它类似于队列(Queue),但是每个元素都有一个关联的…

嵌入式Linux平台大文件生成以及处理方法

在日常工作中,为了验证某些场景下的功能,经常需要人为构造一些大文件进行测试,有时需要用大文件来测试下载速度,有时需要用大文件来覆盖磁盘空间;偶尔会看到一些网络博文会教大家如何构造大文件;但是当需要…

杨中科 ASP.NET DI综合案例

综合案例1 需求说明 1、目的:演示DI的能力; 2、有配置服务、日志服务,然后再开发一个邮件发送器服务。可以通过配置服务来从文件、环境变量、数据库等地方读取配置,可以通过日志服务来将程序运行过程中的日志信息写入文件、控制台、数据库等。 3、说明…

第三百四十九回

文章目录 1. 概念介绍2. 原理与方法2.1 知识对比2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"加密包crypto"相关的内容,本章回中将介绍characters包.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 在项目中会遇到获取字…

Django实战:部署项目 【资产管理系统】,Django完整项目学习研究(项目全解析,部署教程,非常详细)

导言 关于Django,我已经和大家分享了一些知识,考虑到一些伙伴需要在实际的项目中去理解。所以我上传了一套Django的项目学习源码,已经和本文章进行了绑定。大家可以自行下载学习,考虑到一些伙伴是初学者,几年前&#…

OpenAI又出王炸,Sora是否要开启视频AI新时代?

OpenAI又出王炸,Sora是否要开启视频AI新时代? 关注微信公众号 DeepGoAI 前几天我们还在讨论 如何让ChatGPT3.5变得更聪明 今天OpenAI就带着新王炸出现了 如同ChatGPT一般 在计算机领域掀起轩然大波 开启真正视频AI新时代 那就是 Sora 很多同学可…

结构体对齐规则及为什么会有结构体对齐

前言: 大家在学习结构体中,在计算结构体大小时想必会很疑惑,为什么结构体的大小不是按照常理像数组一样一个字节一个字节的挨在一起放?今天带大家一起深入探讨一下背后的规则和原因。 结构体对齐规则: 结构体对齐其实…

离散数学截图2

为什么G中阶大于2的元素,一定有偶数个 在有限群G中,阶大于2的元素个数一定是偶数的原因如下: 设 aaa 是群G中一个阶大于2的元素,那么根据群的定义和阶的概念(即某个元素的幂次使得其等于单位元的最小正整数&#xff…

【Linux】 Linux 小项目—— 进度条

进度条 基础知识1 \r && \n2 行缓冲区3 函数介绍 进度条实现版本 1代码实现运行效果 版本2 Thanks♪(・ω・)ノ谢谢阅读!!!下一篇文章见!!! 基础知识 1 \r &&a…

linux 安装docker

目录 环境 操作步骤 1 下载脚本 2 执行脚本 3 检查docker版本,证明安装成功 环境 阿里云 ubuntu 22.04 64位 操作步骤 参考linux系统安装docker-腾讯云开发者社区-腾讯云 (tencent.com) 1 下载脚本 curl -fsSL https://get.docker.com -o get-docker.sh …

牛客小白月赛87

说明 年后第一次写题,已经麻了,这次的题很简单但居然只写了两道题。有种本该发挥80分的水平,但是只做出了20分的水平的感觉。不过剩下几个题(除了G题),比完赛一小时内就AC了。欢迎大家交流学习。&#xff0…

OpenCV 笔记(22):图像的缩放——最近邻插值、双线性插值算法

1. 图像缩放 1.1 简介 图像缩放是指通过增加或减少像素来改变图像尺寸的过程,是图像处理中常见的操作。图像缩放会涉及效率和图像质量之间的权衡。 图像放大(也称为上采样或插值)的主要目的是放大原图像,以便在更高分辨率的显示设…