WebDriverWait 显示等待
expected_conditions 条件判断
selenium有三种等待方式:
1、强制等待
sleep(10),无论浏览器是否加载完,都得等10s
2、隐形等待
implicitly_wait(10),即设置一个最长等待时间,如果在规定时间内完成加载,则执行下一步,否则一直等到时间截止;
3、显示等待
WebDriverWait( driver, 超时时间, 调用频率 ,忽略异常). until(可执行方法,超时时返回的信息)
eg: WebDriverWait( driver, 10 ) #条件一旦满足,执行下一步,否则继续等待
until_not 与until相反 until是当某元素出现或什么条件成立则继续执行, until_not是当某元素消失或什么条件不成立则继续执行,参数也相同。
presence_of_element_located # 判断某个元素是否被加到了dom树里,并不代表该元素一定可见。一个只要一个符合条件的元素加载出来就通过; presence_of_all_elements_located # 一个必须所有符合条件的元素都加载出来才行 element_to_be_clickable # 判断某个元素中是否可见并且是enable的,这样的话才叫clickable打开淘宝链接,输入关键字进行搜索
举例:淘宝网搜索关键字 “糖果”
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Firefox() # 调用Firefox浏览器
wait = WebDriverWait(browser,10) # 显示等待10s
法一: find_element_by_name
browser.get("https://www.taobao.com") # go to the taobao home page
input= wait.until(lambda x:x.find_element_by_name('q')) # 意思就是在10秒内等待某个按钮被定位到,咱们再去点击。
# input = browser.find_element_by_name('q')
input.send_keys("糖果") # type in the search
input.submit() # submit the form
print(browser.title) # the page is ajaxy so the title is originally this: 淘宝网 - 淘!我喜欢
法二: 条件判断 expected_conditions
def search():
print('正在搜索...')
try:
browser.get('https://www.taobao.com') #用这个网页'https://s.taobao.com',无法输入keywords
input=wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR,'#q')) #打开淘宝,右击查看元素,定位到搜索框,选择对应代码,复制-CSS选择器,其实就是‘#q’。
)
# 判断是否可以点击 ,可以不要
# submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button'))) # 这里是用google浏览器访问的
# submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_SearchForm > div.button'))) # 这里是用 Firefox 浏览器访问的,出错了
input.send_keys("糖果") #模拟操作,输入内容
input.submit()
print(browser.title) # 淘宝网 - 淘!我喜欢
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total'))) #页数
return total.text
except TimeoutException :
return search()
if __name__=='__main__':
total = search()
total = int(re.compile('(\d+)').search(total).group(1)) # 用正则表达式提取数字100
print(total) #100
完整代码
import re
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq #获取整个网页的源代码
from config import * #可引用congif的所有变量
import pymongo
import pymysql
# client=pymongo.MongoClient(MONGO_URL)
# db = client[MONGO_DB]
# 按综合排序 100页
# 打开淘宝链接,输入‘美食’,搜索
# 自动翻页:先得到总页数,再转到 _ 页,确定
#
# browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
# browser =webdriver.Chrome()
browser = webdriver.Firefox()
wait = WebDriverWait(browser,10)
def search():
print('正在搜索...')
try:
browser.get('https://www.taobao.com') #用这个网页'https://s.taobao.com',无法输入keywords
input=wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR,'#q')) #打开淘宝,右击查看元素,定位到搜索框,选择对应代码,复制-CSS选择器,其实就是‘#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'))) #页数
return total.text
except TimeoutException :
return search()
# 翻页
def next_page(page_number):
print('正在翻页',page_number)
try:
input = wait.until(
# 输入框
EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > input')) # 打开淘宝,右击查看元素,定位到搜索框,选择对应代码,复制-CSS选择器,其实就是‘#q’。
)
# 搜索按钮
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 :
next_page(page_number)
# 解析,获取每页的商品并输出
def get_products():
wait.until(EC.presence_of_all_elements_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 = {
# 'picture':item.find('.pic .img').attr('src'),#用find去获取内部元素,选择器是 pic,img,用attr获取属性
'image': item.find('.pic .img').attr('data-src'), # 用find去获取内部元素,选择器是 pic,img,用attr获取属性
'shop_id': item.find('.shop').find('a').attr('data-userid'), # 店铺 id
'data_id': item.find('.shop').find('a').attr('data-nid'), # 商品 id
'link': item.find('.pic-box-inner').find('.pic').find('a').attr['href'],
'price':item.find('.price').text()[1:-3], # 用text获取内容
'deal':item.find('.deal-cnt').text()[:-3],
'title':item.find('.title').text().replace(' ',''),
'shop':item.find('.shop').text(),
'location':item.find('.location').text()
}
# print(product)
# print(product['location'])
save_to_mysql(product)
'''
def main():
try:
# search()
total=search() # 此时 total = ‘共 100 页,’
total=int(re.compile('(\d+)').search(total).group(1)) # 用正则表达式提取数字100
# print(total)
for i in range(2,total+1):
next_page(i)
except Exception:
print('出错啦')
finally: # 不管有没有异常,都要执行此操作
browser.close() # 关浏览器
'''
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)#显示当前爬取网页的页数
print ('搞定%d'%i)
def save_to_mysql(product):
# print(product['location'])
#,use_unicode = False
try:
conn = pymysql.connect(host='localhost', user='root', passwd=' ', db='test1', port=3306,charset='utf8' )
cur = conn.cursor() # 创建一个游标对象
sql = """INSERT INTO women_clothes_zonghe VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
cur.execute(sql, (product['shop_id'],product['shop'], product['link'],product['data_id'], product['title'], product['price'], product['location'],product['deal'],product['image']))
# cur.execute(sql)
print('- - - - - 数据保存成功 - - - - -')
cur.close()
conn.commit()
conn.close() # 关闭数据
except pymysql.Error as e:
print(e)
if __name__=='__main__':
# 连接数据库
conn = pymysql.connect(host='localhost', user='root', passwd=' ', db='test1', port=3306,charset="utf8")
cur = conn.cursor() # 创建一个游标对象
cur.execute("DROP TABLE IF EXISTS women_clothes_zonghe") # 如果表存在则删除
# 创建表sql语句
sqlc = """CREATE TABLE women_clothes_zonghe(
shop_id VARCHAR(500),
shop VARCHAR(500),
link VARCHAR(1000),
data_id varchar(100),
title VARCHAR(1000),
price VARCHAR(500),
location VARCHAR(500),
deal VARCHAR(500),
image VARCHAR(1000)
)"""
cur.execute(sqlc) # 执行创建数据表操作
main()
还可以通过偏移量进行搜索