Python爬虫实战03:用Selenium模拟浏览器爬取淘宝美食
2018-03-30 20:31
821 查看
1 目标站点分析
淘宝页面信息很复杂的,含有各种请求参数和加密参数,如果直接请求或者分析Ajax请求的话会很繁琐。所以我们可以用Selenium来驱动浏览器模拟点击来爬取淘宝的信息。这样我们只要关系操作,不用关心后台发生了怎样的请求。这样有个好处是:可以直接获取网页渲染后的源代码。输出 page_source 属性即可。
这样,我们就可以做到网页的动态爬取了。缺点是速度相比之下比较慢。
2 流程框架
搜索关键词利用Selenium驱动浏览器搜索关键字,得到查询结果后的商品列表。
分析页码并翻页
得到商品页码数,模拟翻页,得到后续页面的商品列表。
分析提取商品内容
利用PyQuery分析源码,解析得到商品列表。
存储至MongoDB
将商品列表信息存储到数据库MongoDB。
3 爬虫实战
3.1 搜索商品信息 search()
首先声明一个浏览器对象browser,有头或者无头。有头的是带界面的,每步操作你都可以看到。无头则是不带界面,在后台运行,速度较快,这里选择无头chrome,配置参数如下。
可能会出错的地方用
try...except包含起来,保证程序的正常运行。如果发生错误,再次搜索。
然后进入淘宝首页,检查源代码,找到输入框的元素和搜索按钮的元素,可右键复制为css选择器。这里就可以输入文字,以及点击按钮。
selenium之等待。防止元素还没加载完成就运行下一步而报错。 调用
WebDriverWait(browser, 10),后面会频繁调用,所以这里改写为
wait。关于selenium等待的 更多用法,点击文档。
# browser = webdriver.Chrome() # 有头chrome # 无头chrome 设置参数 chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') browser = webdriver.Chrome(chrome_options=chrome_options) wait = WebDriverWait(browser, 10) # 改写一下,后面会频繁应用
def search(): """搜索商品信息""" print('正在保存第{}页'.format(1)) try: browser.get('https://www.taobao.com') # 声明搜索框元素,并且设置等待,presence_of_element_located条件是判断已经加载出来 input = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, "#q")) # 这里的css选择器,右键网页源代码复制可得 ) # 声明搜索按钮,等待,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() # 点击按钮 # total 为总页数 presence_of_element_located判断total元素已经加载完成 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() # 如果发生错误,再次搜索。
3.2 翻页 next_page(page_number)
在页码框中输入页码,点击按钮实现翻页。检查高亮元素是否在当前代码判断是否翻页成功,这里用到等待条件text_to_be_present_in_element
def next_page(page_number): """下一页 """ print('正在保存第{}页'.format(page_number)) try: input = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input")) # 这里的css选择器,右键网页源代码复制可得 ) # 等待,判断按钮是可以点击的 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) # 若失败,在试一次
3.3 获取商品信息 get_products()
这里用chrome的工具分析出来的代码,右键复制的css选择器不知道为什么不行。所以用的是css选择器的另外一种写法。def get_products(): """获取商品信息""" # 判断items元素加载成功 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() # items()返回一个生成器,生成每个item for item in items: product = { 'image': item.find('.pic .img').attr('src'), 'price': item.find('.price').text().replace('\n', ''), '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)
3.4 保存到数据库 save_to_mongo(result)
新建一个配置文件 config.py,保存了连接mongodb所需的参数。"""config.py""" MONGO_URL = 'localhost' MONGO_DB = 'toabao' MONGO_TABLE = 'meishi'
client = pymongo.MongoClient(MONGO_URL) db = client[MONGO_DB]
def save_to_mongo(result): """保存到数据库""" try: if db[MONGO_TABLE].insert(result): print('存储到数据库成功', result) except Exception: print("存储失败")
3.5 主函数 main()
def main(): try: total = search() total = int(re.compile('(\d+)').search(total).group(1)) # 强制转换为int类型 for i in range(2, total + 1): next_page(i) except Exception: print('something wrong~!') finally: # 保证浏览器关闭 browser.close()
3.6 头文件
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 selenium.webdriver.chrome.options import Options import pymongo from config import *
3.7 运行
if __name__ == '__main__': main()
3.8 结果
3.9 注意
多用try…except…finally保证程序的正常运行。使用Selenium中,记得在关键操作前加入等待判定,确保所需元素加载完成或者达到我们想要的状态。
相关文章推荐
- Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
- Python2.7 淘宝爬虫selenium 模拟浏览器
- 使用Selenium模拟浏览器抓取淘宝商品美食信息
- python3 [爬虫入门实战] 爬虫之selenium 模拟QQ登陆抓取好友说说内容(暂留)
- 浅谈python爬虫使用Selenium模拟浏览器行为
- Python爬虫实战(5):模拟登录淘宝并获取所有订单(1)
- Python爬虫实战五之模拟登录淘宝并获取所有订单
- Python爬虫实战(5):模拟登录淘宝并获取所有订单(1)
- Python爬虫之selenium爬虫,模拟浏览器爬取天猫信息
- python 针对selenium+phontomjs等模拟浏览器爬虫的反爬技术点
- 使用python利器selenium工具模拟浏览器运行并爬取淘宝商品信息
- Python爬虫实战(5):模拟登录淘宝并获取所有订单
- python爬虫:使用Selenium模拟浏览器行为
- Python爬虫实战八之利用Selenium抓取淘宝匿名旺旺
- Python爬虫实战八之利用Selenium抓取淘宝匿名旺旺
- python3 [爬虫实战] 微博爬虫京东客服之Selenium + Chrom浏览器的使用(上)
- python爬虫实战--selenium验证码保存+多线程多标签+自动点击+完整代码
- 【Python】 Selenium 模拟浏览器 寻路
- Python爬虫(四)——模拟登录imooc实战(利用cookie)
- Python 自动化测试chrome driver(模拟浏览器进行爬取淘宝商品信息)