赞
踩
打开淘宝网首页,我们需要在搜索框输入商品名称,然后点击搜索按钮提交。
打开浏览器开发者工具,找到输入框和提交按钮。输入框的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打开登录界面扫码登录。
(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)运行结果
(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"未审核")
以上是三种选择下拉框的方式,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。
全部取消选择
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")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。