[爬虫笔记04] 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

(2)设置Chrome浏览器驱动

browser = webdriver.Chrome()
browser.set_window_size(1280,800)
wait = WebDriverWait(browser, 10)
KEYWORD = '美食'

(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("扫码后请按回车登录:")

(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()

(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)

(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)

(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)

(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()

(9)运行

if __name__ == '__main__':
    main()

(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()

(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

(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()

(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>

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"未审核")

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

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

全部取消选择

select.deselect_all()

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

alert = driver.switch_to_alert()

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

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

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

for handle in driver.window_handles:
    driver.switch_to_window(handle)

(7)页面前进和后退

driver.forward()     #前进
driver.back()        # 后退

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

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

删除Cookies,用法如下:

# By name
driver.delete_cookie("CookieName")

# all
driver.delete_all_cookies()

(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()

内置条件

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

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

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")
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法爬取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个完整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法爬取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个完整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法爬取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个完整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值