1/25
# 导入所需的库
from selenium import webdriver
import time
import re
import csv
import os
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# 定义一个函数,用于将商品销量中的中文单位转换为整数
def convert_quantity(quantity):
# 定义中文单位与数值的映射关系
units = {
'万': 10000,
'千': 1000,
'百': 100
}
# 去除非数字字符,但保留单位字符
numeric_part = re.sub(r'[^\d万千百]', '', quantity)
# 将数字部分转换为整数
number = 0
for unit, multiplier in units.items():
if unit in numeric_part:
number = int(numeric_part.replace(unit, '')) * multiplier
break
else:
# 如果没有单位,直接转换为整数
number = int(numeric_part)
# 处理销量中带有 '+' 的情况
if '+' in quantity:
return number
return number
# 定义主爬虫函数,参数 key 是搜索关键词
def spiderMain(key):
# 定义初始化函数,用于创建或清空 CSV 文件
def init():
# 如果文件存在,先删除
if os.path.exists('data.csv'):
os.remove('data.csv')
# 创建 CSV 文件并写入表头
with open('data.csv', 'a', encoding='utf-8') as f:
fileWriter = csv.writer(f)
fileWriter.writerow(
['type', 'title', 'price', 'buy_len', 'img_src', 'name', 'address', 'ifFreeDelivert', 'href',
'nameHref'])
# 定义搜索商品的函数
def searchProduct(key):
# 在搜索框中输入关键词
browser.find_element(By.ID, value='q').send_keys(key)
# 点击搜索按钮
browser.find_element(By.XPATH, '//*[@id="J_TSearchForm"]/div[1]/button').click()
# 定义获取商品信息的函数
def getProduct(count):
# 获取页面中所有商品的元素
items = browser.find_elements(By.XPATH, '//div[@class="Content--contentInner--QVTcU0M"]/a')
# 初始化滚动位置和滚动步长
scroll_position = 0
scroll_amount = 200
max_scroll = 5300
# 如果是第一次调用,初始化 CSV 文件
if count == 0:
init()
# 遍历每个商品元素
for a in items:
try:
count = count + 1
# 获取商品类型(搜索关键词)
type = key
# 获取商品标题
title = a.find_element(By.XPATH,
'.//div[@class="Title--descWrapper--HqxzYq0 Title--normalMod--HpNGsui"]//span').text
# 获取商品价格
price = a.find_element(By.XPATH, './/span[@class="Price--priceInt--ZlsSi_M"]').text + \
a.find_element(By.XPATH, './/span[@class="Price--priceFloat--h2RR0RK"]').text
# 获取商品销量,并转换为整数
buy_len = a.find_element(By.XPATH, './/span[@class="Price--realSales--FhTZc7U"]').text
buy_len = convert_quantity(buy_len)
# 获取商品图片的 URL
img_src = a.find_element(By.XPATH,
'.//div[@class=" MainPic--mainPicWrapper--iv9Yv90"]/img').get_attribute('src')
# 获取店铺名称
name = a.find_element(By.XPATH, './/a[@class="ShopInfo--shopName--rg6mGmy"]').text
# 获取店铺地址
address = a.find_elements(By.XPATH, './/div[@class="Price--procity--_7Vt3mX"]')[0].text
# 获取商品详情页的 URL
href = a.get_attribute('href')
# 获取店铺链接
nameHref = a.find_element(By.XPATH, './/a[@class="ShopInfo--shopName--rg6mGmy"]').get_attribute('href')
# 判断是否包邮
ifFreeDelivert = ''
try:
# 获取商品的包邮信息
isFreeDelivertList = a.find_elements(By.XPATH, './/div[@class="Card--doubleCard--wznk5U4"]//div/span')
ifFreeDelivert = '不包邮'
for i in isFreeDelivertList:
if '包邮' in i.text:
ifFreeDelivert = '包邮'
except:
ifFreeDelivert = '不包邮'
# 将商品信息保存到 CSV 文件中
save_to_csv(type, title, price, buy_len, img_src, name, address, ifFreeDelivert, href, nameHref)
# 如果滚动位置未达到最大值,滚动页面
if scroll_position < max_scroll:
scroll_script = f"window.scrollBy(0, {scroll_amount});"
browser.execute_script(scroll_script)
scroll_position += scroll_amount
except:
# 如果发生异常,跳过当前商品
count -= 1
continue
# 每爬取 10 个商品,打印当前进度
if count % 10 == 0:
print('已经爬取%d页数据了' % count)
# 点击下一页按钮
button = browser.find_element(By.XPATH,
'//button[@class="next-btn next-medium next-btn-normal next-pagination-item next-next"]')
actions = ActionChains(browser)
actions.move_to_element(button).click().perform()
print('正在翻页')
time.sleep(3)
# 递归调用自身,爬取下一页的商品
getProduct(count)
# 定义保存商品信息到 CSV 文件的函数
def save_to_csv(type, title, price, buy_len, img_src, name, address, ifFreeDelivert, href, nameHref):
with open('data.csv', 'a', encoding='utf-8', newline='') as f:
myWriter = csv.writer(f)
myWriter.writerow([type, title, price, buy_len, img_src, name, address, ifFreeDelivert, href, nameHref])
# 定义主函数,用于启动爬虫
def main():
# 搜索商品
searchProduct(key)
# 获取商品信息
getProduct(0)
# 调用主函数
main()
# 程序入口
if __name__ == '__main__':
# 设置 ChromeDriver 的路径
service = Service('chromedriver.exe')
# 配置 Chrome 浏览器选项
option = webdriver.ChromeOptions()
# 连接到已启动的 Chrome 浏览器实例
option.add_experimental_option("debuggerAddress", "localhost:9222")
# 初始化 WebDriver
browser = webdriver.Chrome(service=service, options=option)
# 执行 CDP 命令,隐藏 WebDriver 标志
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
# 打开淘宝网站
browser.get('https://www.taobao.com/')
# 调用爬虫主函数,搜索关键词为 '电脑'
spiderMain('电脑')

浙公网安备 33010602011771号