使用selenium爬取淘宝页面中的商品信息

7 篇文章 0 订阅
4 篇文章 0 订阅

一、分析
淘宝页面中的商品都是用js动态加载的,所以使用selenium模块抓取内容
1.首先分析如何用关键字搜索内容
2.打开浏览器
3.然后分析页面结构,抓取信息
4.其次获取商品具体信息的话需要打开二级页面
5.需要找到下一页的按钮用于模拟点击下一页,从而获取所有页面的相关信息

二、开始操作
1.首先分析如何用关键字搜索内容
注意到页面的规律为https://s.taobao.com/search?q=关键字

所以可以使用代码url="https://s.taobao.com/search?q={kw}".format(kw=urllib.parse.quote("衣服"))

这里的衣服是我随便打的数据,在应用到scrapy框架中可以使用变量代替
2. 打开浏览器
测试阶段需要看浏览器具体做了什么操作,所以我使用了用显示方式打开:

from selenium import webdriver
driver=webdriver.Chrome()

当程序没有什么问题了再用隐藏方式开启浏览器,这样就不用加载浏览器里面的图片等信息了,速度会快很多很多:

option=webdriver.ChromeOptions()
option.add_argument("headless")
driver = webdriver.Chrome(options=option)

获取主页面:

main_driver=driver.current_window_handle

3.然后分析页面结构,抓取信息
加载里面所有商品,使用一个js让他执行,移动垂直滚动条到最下面:

js="window.scrollTo(0,document.body.scrollHeight)"
driver.execute_script(js)

发现他的商品都放在这个div下,所以用goods保存所有div

goods=driver.find_elements_by_xpath('//div[contains(@class,"J_MouserOnverReq")]')

开始遍历goods,这些是我要获取的内容:

for item in goods:
	price=item.find_element_by_xpath('.//div[2]/div[1]/div/strong').text
	title=item.find_element_by_xpath('.//div[2]/div[2]/a').text
	shop_name=item.find_element_by_xpath('.//div[2]/div[3]/div[1]/a/span[2]').text
	origin=item.find_element_by_xpath('.//div[2]/div[3]/div[2]').text

4.接下来是处理二级页面即goods里面具体的内容,我做例子,只获取里面的详细信息一栏的内容:

	item.click()
	driver.switch_to.window(driver.window_handles[-1])
    js="window.scrollTo(0,1000)"
    driver.execute_script(js)
    time.sleep(1)

good是我获取的商品,good.click()点击这个商品会跳转到新的页面,于是使用driver.switch_to.window()方法,这个方法是用来跳转driver的,driver.window_handles这个是一个列表,这是一个存放所有的窗口的列表,刚打开一个窗口就会在这个列表里面添加一个窗口元素,
driver.window_handles[-1]这个就表示最后一个打开的窗口,最后一个sleep主要是为了辅助让他加载完成
5.找到下一页,模拟点击下一页

    try:
        next_page = WebDriverWait(driver, 3, 0.2).until(lambda x: x.find_element_by_xpath('//span[contains(text(),"下一页")]/..'))
    except Exception as e:
        print(e)
        break
    else:
        next_page.click()

对于这段代码做如下解释:

 WebDriverWait(driver, 3, 0.3).until(lambda x: x.find_element_by_xpath('//span[contains(text(),"下一页")]/..'))

拆分解释:
driver是驱动程序,3是最长等待时间,0.3也就是多久再去检查是否存在,until就是具体找的内容,知道找到里面的内容并且在3秒内,until里面用的是一个匿名函数,其中的参数x值得就是哪个driver驱动程序,他要做的事情就是去找下一页所在的标签,x.find_element_by_xpath('//span[contains(text(),"下一页")]/..')这个类似driver.find… 通过分析,他的下一页按钮在一个a标签下包裹着,…表示他的上一级。
整段代码的解释:3秒内去等待加载一个’内容为“下一页”的span标签的父级标签‘,每0.3秒检查一下是否找到了,如果3秒内找到了则返回结果(结果为一个标签的对象),如果三秒都没有找到则抛出异常,所以这里要用try,except方法
对于我上面整体的代码来说就是如果找到了下一页则点击下一页,如果没找到则退出,这个退出就是说页面中没有下一页,或者下一页不可点击,其中对于下一页不可点击我没做判断,我假定最后一页没有下一页按钮,则当找不到下一页就说明是最后一页就可以退出了。

总结:
对于这个例子来说,在操作的过程中总是遇到StaleElementReferenceException的异常,我的解决方案是在next_page.click()之后sleep两秒,用于缓解他的加载,避免造成错误,但是这一定不是最好的办法。暂时我就这样做了。有更好的办法我会更新博客。

完整代码如下:

import time
import urllib.parse
from selenium import webdriver

# option=webdriver.ChromeOptions()
# option.add_argument("headless")
# driver = webdriver.Chrome(options=option)
from selenium.webdriver.support.wait import WebDriverWait

driver=webdriver.Chrome()
kw="衣服"
url="https://s.taobao.com/search?q={kw}".format(kw=urllib.parse.quote(kw))
driver.get(url)
js="window.scrollTo(0,document.body.scrollHeight)"
driver.execute_script(js)

main_driver=driver.current_window_handle

while True:
    time.sleep(2)
    goods=driver.find_elements_by_xpath('//div[contains(@class,"J_MouserOnverReq")]')
    for item in goods:
        price=item.find_element_by_xpath('.//div[2]/div[1]/div/strong').text
        title=item.find_element_by_xpath('.//div[2]/div[2]/a').text
        shop_name=item.find_element_by_xpath('.//div[2]/div[3]/div[1]/a/span[2]').text
        origin=item.find_element_by_xpath('.//div[2]/div[3]/div[2]').text
        item.click()
        driver.switch_to.window(driver.window_handles[-1])
        js="window.scrollTo(0,1000)"
        driver.execute_script(js)
        time.sleep(1)
        try:
            tag_standard = WebDriverWait(driver, 5, 0.2).until(lambda x:x.find_element_by_xpath('//*[@id="J_TabBar"]/li[2]/a'))
        except:
            tag_standard=None
        if tag_standard:
            tag_standard.click()
            try:
                tag_table = driver.find_element_by_xpath('//table[@class="tm-tableAttr"]')
                goods_info = tag_table.text
            except:
                goods_info=None
            print(goods_info)
            driver.close()
            driver.switch_to.window(main_driver)

    try:
        next_page = WebDriverWait(driver, 3, 0.2).until(lambda x: x.find_element_by_xpath('//span[contains(text(),"下一页")]/..'))
    except Exception as e:
        print(e)
        break
    else:
        next_page.click()
driver.quit()
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值