代码中的注释是自己加的,为了以后能让自己明白写的是什么.如果有错的地方请大家给小弟指出来.
代码是从B站上学习python爬虫中写的.
spider.py
import re
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from config import *
import pymongo
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
# 使用webdriver打开chrome,打开淘宝页面,搜索美食关键字,返回总页数
def search():
try:
browser.get('https://www.taobao.com')
# 判断输入框是否已经加载
#presence_of_element_located()判断一个元素是否存在。通过CSS选择器来判断#q是否存在
input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#q')))
# 判断搜索按钮是否可以进行点击操作
# element_to_be_clickable判断元素是否点击,它处于可见和启动状态
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button')))
# 输入美食,点击搜索按钮
input.send_keys('美食')
submit.click()
# 使用css_selector找到显示总页面的元素,判断是否出现并获取其中文字
total = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total')))
get_products()
print(total)
return total.text
except TimeoutException:
print('timeout!')
return search()
def next_page(page_num):
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_num)
submit.click()
#根据高亮区域显示数字来判断页面是否跳转成功
# 判断元素是否有page_num文本信息
wait.until(EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page_num)))
get_products()
except TimeoutException:
next_page(page_num)
def get_products():
test= wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))
print(type(test))
#获取网页的源码
html = browser.page_source
#用pyquery进行解析,获取需要的信息
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)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print('存储成功', result)
except Exception:
print('存储失败:',result)
if __name__ == '__main__':
total = search()
total = int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total + 1):
next_page(i)
config.py文件
MONGO_URL='localhost'
MONGO_DB='taobao'
MONGO_TABLE='product'
WebDriver提供两种类型的等待:显式等待和隐式等待
WebDriverWait()在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超出设置时间检测不到抛出异常。具体格式如下:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
Driver---WebDriver的驱动程序
Timeout—最常超是时间,默认以秒为单位
Poll_frequency—休眠时间的间隔时间,默认为0.5秒
Ignored_exception—超时后的异常信息,默认情况下抛NoSuchElementException异常。
WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明
Until(method,message=’’):调用该方法提供的驱动程序作为一个参数,直到返回值为True。
Until_not(method,message=‘’):调用该方法提供的驱动程序作为一个参数,直到返回值为false。
通过as关键词对expected_conditons重名为EC,并调用presence_of_element_located()判断元素是否存在。
Expected_conditions类提供一些预期条件的实现
Title_is | 用于判断标题是否为xx。 |
Title_contains | 用于判断标题收包含xx信息。 |
Presence_of_element_located | 元素是否存在 |
Visibility_of | 元素是否可见 |
Presence_of_all_elements_located | 判断一组元素是否存在 |
Text_to_be_present_in_element | 判断元素是否有xx文本信息 |
Text_to_be_present_in_element_value | 判断元素值是否有xx文本信息 |
Frame_to_be_available_and_switch_to_it | 表单是否可用,并切换到该表单 |
Invisibility_of_element_located | 判断元素是否隐藏 |
Element_to_be_clickable | 判断元素是否点击,它处于可见和启动状态 |
Staleness_of | 等到一个元素不再是依附于DOM |
Element_to_be_selected | 被选中的元素 |
Element_located_to_be_selected | 一个期望的元素位于被选中 |
Element_selection_state_to_be | 一个期望检查如果给定的元素被选中 |
Element_located_selection_state_to_be | 期望找到一个元素并检查是否选在状态 |
Alert_is_present | 预期一个警告信息 |
Is_displayed() | 方法也能判断元素是否可见。 |