当前位置:   article > 正文

[爬虫笔记04] Selenium爬取淘宝商品_使用selenium爬取淘宝商品

使用selenium爬取淘宝商品

1.爬取分析

打开淘宝网首页,我们需要在搜索框输入商品名称,然后点击搜索按钮提交。
在这里插入图片描述
打开浏览器开发者工具,找到输入框和提交按钮。输入框的id为 q,提交按钮我们使用css选择器,路径为 #J_TSearchForm > div.search-button > button
在这里插入图片描述
在搜索框输入“美食”,点击搜索按钮,就会跳到商品目录界面。
在这里插入图片描述
我们需要获取商品的总页数。
在这里插入图片描述
使用css选择器提取,路径为 #mainsrp-pager > div > div > div > div.total
在这里插入图片描述
那么怎么翻页呢?这里我们通过页码输入框来进行翻页操作。在页码输入框中输入数字,点击确定按钮,就可以进行翻页。
在这里插入图片描述
页码输入框的css选择器路径为 #mainsrp-pager > div > div > div > div.form > input
在这里插入图片描述
确定按钮的css选择器路径为 #mainsrp-pager > div > div > div > div.form > span.btn.J_Submit
在这里插入图片描述
那么怎么确定已经翻到那页了呢?通过观察我们发现,当前页面到第几页,第几页的页码块就会变成橘色,< li >标签就会多一个active的class,页码块的css选择器路径为 #mainsrp-pager > div > div > div > ul > li.item.active > span
在这里插入图片描述
处理好翻页,就可以开始提取商品信息了。所有的商品放在id为 mainsrp-itemlist 的< div >里,每个商品放在class为 item 的< div >里,商品图片放在class为 pic-box 的< div >里,商品文字信息放在class为 ctx-box 的< div >里。单个商品的css选择器路径为 #mainsrp-itemlist .items .item
在这里插入图片描述
使用pyquery来解析即可。
在这里插入图片描述
在这里插入图片描述
到这里基本就结束了,但是由于淘宝会检测到是Selenium在控制浏览器,搜索商品时会跳出登录界面,所以这里还需要进行登录操作,我们在爬取之前先让Selenium打开登录界面扫码登录。
在这里插入图片描述

2.代码实现

(1)导入包

import re
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import pymongo
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(2)设置Chrome浏览器驱动

browser = webdriver.Chrome()
browser.set_window_size(1280,800)
wait = WebDriverWait(browser, 10)
KEYWORD = '美食'
  • 1
  • 2
  • 3
  • 4

(3)登录
为了给登录留充足的时间,这里打开登录界面,扫码登录成功后,再在命令行按回车运行后面的代码。

def login():
    browser.get('https://login.taobao.com/member/login.jhtml?redirectURL=http%3A%2F%2Fbuyertrade.taobao.com%2Ftrade%2Fitemlist%2Flist_bought_items.htm%3Fspm%3D875.7931836%252FB.a2226mz.4.66144265Vdg7d5%26t%3D20110530')
    input("扫码后请按回车登录:")
  • 1
  • 2
  • 3
'
运行

(4)搜索商品
先打开淘宝首页,等到输入框和提交按钮加载出来后,在输入框输入内容,点击提交按钮,等待总页数加载出来后,获取第一页的商品信息,返回总页数。如果超时,则重新执行。

def search():
    try:
        browser.get('https://www.taobao.com')
        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()
        total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total')))
        get_products()
        return total.text
    except TimeoutException:
        return search()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
'
运行

(5)翻页
等到页码输入框和确定按钮加载出来后,清除页码输入框中的内容,重新输入页码,点击确定按钮,等到输入页的页码块激活后,获取该页产品。如果超时,则重新执行。

def next_page(page_number):
    print("正在爬取第" + str(page_number) + "页")
    try:
        input = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input"))
                    )
        submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit')))
        input.clear()
        input.send_keys(page_number)
        submit.click()
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page_number)))
        get_products()
    except TimeoutException:
        return next_page(page_number)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
'
运行

(6)爬取商品信息
等所有的商品加载出来后,使用pyquery解析数据,保存到MongoDB中。

def get_products():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-itemlist .items .item')))
    html = browser.page_source
    doc = pq(html)
    items = doc('#mainsrp-itemlist .items .item').items()
    for item in items:
        product = {
            'image': item.find('.pic .img').attr('src'),
            'price': item.find('.price').text(),
            'deal': item.find('.deal-cnt').text()[:-3],
            'title': item.find('.title').text(),
            'shop': item.find('.shop').text(),
            'location': item.find('.location').text()
                }
        save_to_mongo(product)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
'
运行

(7)保存到MongoDB

MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_COLLECTION = 'product'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]

def save_to_mongo(result):
    try:
        if db[MONGO_COLLECTION].insert(result):
            print('存储到MongoDB成功', result)
    except Exception:
        print('存储到MongoDB失败', result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(8)主函数

def main():
    login()
    total = search()
    total = int(re.compile('(\d+)').search(total).group(1))
    for i in range(2, total + 1):
        next_page(i)
    browser.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
'
运行

(9)运行

if __name__ == '__main__':
    main()
  • 1
  • 2

(10)运行结果
在这里插入图片描述

3.Selenium用法

(1)基本用法

from selenium import webdriver

#调用键盘按键操作时需要引入的Keys包
from selenium.webdriver.common.keys import Keys

#调用环境变量指定的PhantomJS()浏览器创建浏览器对象
driver = webdriver.PhantomJS()

#如果没有在环境变量指定PhantomJS位置
driver = webdriver.PhantomJS(executable_path="phantomjs")

#get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择time.sleep(2)
driver.get("https://www.baidu.com")

#获取页面名为wrapper的id标签的文本内容
data = driver.find_element_by_id('wrapper').text

#打印数据内容
print(data)

#打印页面标题“百度一下,你就知道”
print(driver.title)

#生成当前页面快照并保存
driver.save_screenshot('baidu.png')

#id = 'kw'是百度搜索输入框,输入字符串“长城”
driver.find_element_by_id('kw').send_keys(u'长城')

#id = 'su'是百度搜索按钮,click()是模拟点击
driver.find_element_by_id('su').click()

#获取新的页面快照
driver.save_screenshot('长城.png')

#打印网页渲染后的源代码
print(driver.page_source)

#获取当前页面Cookie
print(driver.get_cookies())

#ctrl+a全选输入框内容
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')

#crtl+x剪切输入框内容
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x')

#输入框重新输入内容
driver.find_element_by_id('kw').send_keys('itcast')

#模拟Enter回车键
driver.find_element_by_id('kw').send_keys(Keys.ENTER)

#生成新的页面快照
driver.save_screenshot('dat/itcast.png')

#清除搜入框内容
driver.find_element_by_id('kw').clear()

#生成新的页面快照
driver.save_screenshot('dat/itcast1.png')

#获取当前url
print(driver.current_url)

#关闭当前页面,如果只有一个页面,会关闭浏览器
driver.close()

#关闭浏览器
driver.quit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

(2)定位WebElements

find_element_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(3)鼠标动作链
有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入 ActionChains 类来做到:

#导入 ActionChains 类
from selenium.webdriver import ActionChains

# 鼠标移动到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()


# 在 ac 位置单击
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()

# 在 ac 位置双击
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()

# 在 ac 位置右击
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()

# 在 ac 位置左键单击hold住
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()

# 将 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

(4)填充表单
我们已经知道了怎样向文本框中输入文字,但是有时候我们会碰到< select > </ select >标签的下拉框。直接点击下拉框中的选项不一定可行。

<select id="status" class="form-control valid" onchange="" name="status">
    <option value=""></option>
    <option value="0">未审核</option>
    <option value="1">初审通过</option>
    <option value="2">复审通过</option>
    <option value="3">审核不通过</option>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Selenium专门提供了Select类来处理下拉框。 其实 WebDriver 中提供了一个叫 Select 的方法,可以帮助我们完成这些事情:

# 导入 Select 类
from selenium.webdriver.support.ui import Select

# 找到 name 的选项卡
select = Select(driver.find_element_by_name('status'))

select.select_by_index(1)
select.select_by_value("0")
select.select_by_visible_text(u"未审核")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

以上是三种选择下拉框的方式,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。

  • index 索引从 0 开始
  • value是option标签的一个属性值,并不是显示在下拉框中的值
  • visible_text是在option标签文本的值,是显示在下拉框的值

全部取消选择

select.deselect_all()
  • 1

(5)弹窗处理
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:

alert = driver.switch_to_alert()
  • 1

(6)页面切换
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:

driver.switch_to.window("this is window name")
  • 1

也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:

for handle in driver.window_handles:
    driver.switch_to_window(handle)
  • 1
  • 2

(7)页面前进和后退

driver.forward()     #前进
driver.back()        # 后退
  • 1
  • 2

(8)Cookies
获取页面每个Cookies值,用法如下:

for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))
  • 1
  • 2

删除Cookies,用法如下:

# By name
driver.delete_cookie("CookieName")

# all
driver.delete_all_cookies()
  • 1
  • 2
  • 3
  • 4
  • 5

(9)页面等待

显式等待
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。

from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
    # 页面一直循环,直到 id="myDynamicElement" 出现
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

内置条件

title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable – it is Displayed and Enabled.
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

隐式等待
隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/970118
推荐阅读
相关标签
  

闽ICP备14008679号