当前位置:   article > 正文

超详细python实现爬取淘宝商品信息(标题、销量、地区、店铺等)_淘宝月营业额爬虫

淘宝月营业额爬虫

引导      

        因为数据可视化这门课程的大作业要自己爬取数据,想着爬取淘宝的数据,结果找了不少文章都不太行、或者已经失效了等等,就边学边看边写搓了一份代码出来,一是为了记录一下、二是如果大家有需要也可以使用。

首先看最后爬取的数据的效果:

代码部分

引入第三方库

  1. import pymysql
  2. from selenium import webdriver
  3. from selenium.common.exceptions import TimeoutException
  4. from selenium.webdriver.common.by import By
  5. from selenium.webdriver.support.ui import WebDriverWait
  6. from selenium.webdriver.support import expected_conditions as EC
  7. from pyquery import PyQuery as pq
  8. import time
  9. import random

第三方库主要用到了 pymysql 和 selenium ,用pip指令安装即可

  1. pip install pymysql
  2. pip install selenium

全局定义

  1. # 要搜索的商品的关键词
  2. KEYWORD = '衣服'
  3. # 数据库中要插入的表
  4. MYSQL_TABLE = 'goods'
  5. # MySQL 数据库连接配置,根据自己的本地数据库修改
  6. db_config = {
  7. 'host': 'localhost',
  8. 'port': 3306,
  9. 'user': 'root',
  10. 'password': '123456',
  11. 'database': 'datavisible',
  12. 'charset': 'utf8mb4',
  13. }
  14. # 创建 MySQL 连接对象
  15. conn = pymysql.connect(**db_config)
  16. cursor = conn.cursor()
  17. options = webdriver.ChromeOptions()
  18. # 关闭自动测试状态显示 // 会导致浏览器报:请停用开发者模式
  19. options.add_experimental_option("excludeSwitches", ['enable-automation'])
  20. # 把chrome设为selenium驱动的浏览器代理;
  21. driver = webdriver.Chrome(options=options)
  22. # 窗口最大化
  23. driver.maximize_window()
  24. # wait是Selenium中的一个等待类,用于在特定条件满足之前等待一定的时间(这里是15秒)。
  25. # 如果一直到等待时间都没满足则会捕获TimeoutException异常
  26. wait = WebDriverWait(driver, 15)

主函数

  1. # 在 main 函数开始时连接数据库
  2. def main():
  3. try:
  4. pageStart = int(input("输入您想开始爬取的页面数: "))
  5. pageAll = int(input("输入您想爬取的总页面数: "))
  6. search_goods(pageStart, pageAll)
  7. except Exception as e:
  8. print('main函数报错: ', e)
  9. finally:
  10. cursor.close()
  11. conn.close()
  12. #启动爬虫
  13. if __name__ == '__main__':
  14. main()

启动爬虫后输入要开始爬取的页面数、要爬取的页面总数,然后执行search_goods()函数。
(但这里还没有输入就会弹出浏览器,不知道什么原因,要先最小化然后再回到控制台输入)

其他代码

查找商品
  1. # 打开页面后会强制停止10秒,请在此时手动扫码登陆
  2. def search_goods(start_page, total_pages):
  3. print('正在搜索: ')
  4. try:
  5. driver.get('https://www.taobao.com')
  6. # 强制停止10秒,请在此时手动扫码登陆
  7. time.sleep(10)
  8. driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
  9. {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
  10. # 找到搜索输入框
  11. input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
  12. # 找到“搜索”按钮
  13. submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))
  14. input.send_keys(KEYWORD)
  15. submit.click()
  16. # 搜索商品后会再强制停止10秒,如有滑块请手动操作
  17. time.sleep(10)
  18. # 如果不是从第一页开始爬取,就滑动到底部输入页面然后跳转
  19. if start_page != 1 :
  20. # 滑动到页面底端
  21. driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  22. # 滑动到底部后停留1-3s
  23. random_sleep(1, 3)
  24. # 找到输入页面的表单
  25. 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')))
  26. pageInput.send_keys(start_page)
  27. # 找到页面跳转的确定按钮,并且点击
  28. 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]')))
  29. admit.click()
  30. get_goods()
  31. for i in range(start_page + 1, start_page + total_pages):
  32. page_turning(i)
  33. except TimeoutException:
  34. print("search_goods: error")
  35. return search_goods()

        我觉得注释的已经很清楚了,需要注意的是进入淘宝主页后,函数会暂停执行10s,需要在这期间手动扫码登陆一下;搜索关键词跳转到商品页面以后也会暂停10s,防止有滑块验证,如果有也需要手动验证一下。

翻页处理
  1. # 进行翻页处理
  2. def page_turning(page_number):
  3. print('正在翻页: ', page_number)
  4. try:
  5. # 找到下一页的按钮
  6. submit = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/button[2]')))
  7. submit.click()
  8. # 判断页数是否相等
  9. 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)))
  10. get_goods()
  11. except TimeoutException:
  12. page_turning(page_number)
 爬取商品数据
  1. #获取每一页的商品信息;
  2. def get_goods():
  3. # 获取商品前固定等待2-4秒
  4. random_sleep(2, 4)
  5. html = driver.page_source
  6. doc = pq(html)
  7. # 提取所有商品的共同父元素的类选择器
  8. items = doc('div.PageContent--contentWrap--mep7AEm > div.LeftLay--leftWrap--xBQipVc > div.LeftLay--leftContent--AMmPNfB > div.Content--content--sgSCZ12 > div > div').items()
  9. for item in items:
  10. # 定位商品标题
  11. title = item.find('.Title--title--jCOPvpf span').text()
  12. # 定位价格
  13. price_int = item.find('.Price--priceInt--ZlsSi_M').text()
  14. price_float = item.find('.Price--priceFloat--h2RR0RK').text()
  15. if price_int and price_float:
  16. price = float(f"{price_int}{price_float}")
  17. else:
  18. price = 0.0
  19. # 定位交易量
  20. deal = item.find('.Price--realSales--FhTZc7U').text()
  21. # 定位所在地信息
  22. location = item.find('.Price--procity--_7Vt3mX').text()
  23. # 定位店名
  24. shop = item.find('.ShopInfo--TextAndPic--yH0AZfx a').text()
  25. # 定位包邮的位置
  26. postText = item.find('.SalesPoint--subIconWrapper--s6vanNY span').text()
  27. result = 1 if "包邮" in postText else 0
  28. # 构建商品信息字典
  29. product = {
  30. 'title': title,
  31. 'price': price,
  32. 'deal': deal,
  33. 'location': location,
  34. 'shop': shop,
  35. 'isPostFree': result
  36. }
  37. save_to_mysql(product)
插入数据库
  1. # 在 save_to_mysql 函数中保存数据到 MySQL
  2. def save_to_mysql(result):
  3. try:
  4. sql = "INSERT INTO {} (price, deal, title, shop, location, postFree) VALUES (%s, %s, %s, %s, %s, %s)".format(MYSQL_TABLE)
  5. print("sql语句为: " + sql)
  6. cursor.execute(sql, (result['price'], result['deal'], result['title'], result['shop'], result['location'], result['isPostFree']))
  7. conn.commit()
  8. print('存储到MySQL成功: ', result)
  9. except Exception as e:
  10. print('存储到MYsql出错: ', result, e)
随机暂停函数
  1. # 强制等待的方法,在timeS到timeE的时间之间随机等待
  2. def random_sleep(timeS, timeE):
  3. # 生成一个S到E之间的随机等待时间
  4. random_sleep_time = random.uniform(timeS, timeE)
  5. time.sleep(random_sleep_time)

在不同操作的时候插入一个随机暂停执行函数,模拟真人操作(虽然不知道有没有用 o.O? )

疑惑部分

以上就是全部代码,因为我这也是第一用爬虫(甚至第一次用Python),我觉得如果有其他初学者有疑惑的地方可能就是这些代码部分:

  1. wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
  2. wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))
  3. 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')))
  4. 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]')))
  5. wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/button[2]')))
  6. 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)))

element_to_be_clickable、text_to_be_present_in_element等等这些方法的作用请自行搜索。

wait.until()的作用是在完成括号内的操作前一直等待,等待时长是自己定义的,也就是我在全局变量里定义过的wait = WebDriverWait(driver, 15),也就是15秒。

  1. (By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/span[3]/input')
  2. (By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')
  3. 而这些其实就是根据元素选择器找到页面上你需要的元素,
  4. 在淘宝网上按F12,操作看下图:

右键这个元素即可复制选择器或者路径。

数据处理

  1. -- 删除无效数据
  2. DELETE FROM goods WHERE price='' OR deal='' OR title='' OR location=''
  3. -- 只保留一条记录,删除其他重复记录
  4. DELETE g1
  5. FROM goods g1, goods g2
  6. WHERE g1.id > g2.id AND g1.deal = g2.deal AND g1.title = g2.title AND g1.shop = g2.shop
  7. -- 处理月销过万的商品,把万替换为0000
  8. UPDATE goods SET deal = REPLACE(deal, '万', '0000')
  9. WHERE deal LIKE '%万%'
  10. -- 提取销售数量的数字部分,更新对应字段
  11. UPDATE goods
  12. SET deal_count = CAST(REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( deal, '人付款', 1 ), '+', 1 ), ',', '' ) AS SIGNED)
  13. WHERE deal_count is NULL

因为爬取到的销量是“1000+人付款”这种格式,所以要处理一下,提取出数字部分,先自己新建一个字段(我这里叫deal_count),然后按照这些sql从上到下运行一遍即可。

希望可能帮助到大家,共同进步!
完整代码请到github自取

XXXHjf/taobaoCrawler: 淘宝爬虫 (github.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/159344
推荐阅读
相关标签
  

闽ICP备14008679号