Python爬虫实战之抓取淘宝MM照片(三)

紧接着上文,继续探索

抓取JS动态页面内容

  上文的内容,都是对首页内容的抓取和处理,实际上使用urllib2库以及正则表达式也可以完成(当然没有 beautiful soup 方便易用)。这并未能提现到 selenium + phantomJS 的主要用处。本文就会模拟JS渲染的页面翻页。

网页元素定位

《Python爬虫实战之抓取淘宝MM照片(三)》
从该网页的翻页工具条可以看到,如果要翻页,有三种可行方案:

  1. 直接点击页面按钮,可以跳转至该页
  2. 点击 下一页、上一页 按钮,进行页面跳转
  3. 在右边输入页码,点击确定,则跳转至该页

为了方便写循环等因素,我选择第三种方案。

找到对应的html源码如下:
《Python爬虫实战之抓取淘宝MM照片(三)》

使用代码定位

总页数

driver.find_element_by_xpath('//div[@class="paginations"]/span[@class="skip-wrap"]/em').text

页码输入框

driver.find_element_by_xpath('//input[@aria-label="页码输入框"]')

“确定”按钮

driver.find_element_by_xpath('//button[@aria-label="确定跳转"]')

模拟翻页

# 找到页码输入框
pageInput = driver.find_element_by_xpath('//input[@aria-label="页码输入框"]')
pageInput.clear()  # 清除输入框中原有的文本
pageInput.send_keys(str(i+1)) # 输入新页码

# 找到“确定”按钮,并点击
ok_button = driver.find_element_by_xpath('//button[@aria-label="确定跳转"]')
ok_button.click()

遇到的问题

  • 一直读取不到新页面
      在点击”确定”按钮后,进入下一个循环,获取到的还是原来页面信息,一度怀疑调用 click() 是否要获取返回值然后再赋值给driver。也考虑过是否要driver调用什么函数去加载 click() 后的新页面。

      然后经过一番搜索,使用 webdriver.Chrome()查看实际操作后,才意识到,click()之后加载新页面是需要时间!!!所以,在调用 click() 后需要 time.sleep() 一下。

# 睡2秒让网页加载完再去读它的html代码
# http://www.tuicool.com/articles/22eY7vQ
time.sleep(2)
  • 程序运行结束,phantomJS.exe 没有自动关闭
# http://www.jianshu.com/p/9d408e21dc3a
# 之前是使用 driver.close(),但这个不确保关闭 phantomjs.exe
# 会导致一直占用着内存
driver.quit()

第三版结果

可以抓取所有页面的照片

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2017-06-18 22:32:26
# @Author : kk (zwk.patrick@foxmail.com)
# @Link : blog.csdn.net/PatrickZheng

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from bs4 import BeautifulSoup

import requests, urllib2
import os.path
import time

# 设置 Headers
# https://www.zhihu.com/question/35547395
user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36'
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (user_agent)
driver = webdriver.PhantomJS(executable_path='D:\workplace\spider\phantomjs-2.1.1-windows\phantomjs.exe', desired_capabilities=dcap)
driver.get('https://www.taobao.com/markets/mm/mmku')

# 获取总共的页数
pages = int(driver.find_element_by_xpath('//div[@class="paginations"]/span[@class="skip-wrap"]/em').text)
print 'Total pages: %d' % pages

for i in range(1, 3):
    soup = BeautifulSoup(driver.page_source, 'lxml')
    print '第 %d 页:\n' % i
    # 每个MM的展示是放在 属性class=cons_li的div中
    cons_li_list = soup.select('.cons_li')
    lenOfList = len(cons_li_list)
    print lenOfList

    for cons_li in cons_li_list:
        name = cons_li.select('.item_name')[0].get_text().strip('\n')
        print name

        img_src = cons_li.select('.item_img img')[0].get('src')
        if img_src is None:
            img_src = cons_li.select('.item_img img')[0].get('data-ks-lazyload')
        print img_src

        filename = name + os.path.splitext(img_src)[1]
        with open(filename, 'wb') as f:
            # urllib2 可以添加 headers
            # http://www.jianshu.com/p/6094ff96536d
            request = urllib2.Request(img_src if img_src.startswith('http') else 'http:'+img_src, None, headers)
            response = urllib2.urlopen(request)
            f.write(response.read())

    # 找到页码输入框
    pageInput = driver.find_element_by_xpath('//input[@aria-label="页码输入框"]')
    pageInput.clear()
    pageInput.send_keys(str(i+1))

    # 找到“确定”按钮,并点击
    ok_button = driver.find_element_by_xpath('//button[@aria-label="确定跳转"]')
    ok_button.click()

    # 睡2秒让网页加载完再去读它的html代码
    # http://www.tuicool.com/articles/22eY7vQ
    time.sleep(2)

# http://www.jianshu.com/p/9d408e21dc3a
# 之前是使用 driver.close(),但这个不确保关闭 phantomjs.exe
# 会导致一直占用着内存
driver.quit()
print 'done.'

上述源码放到 Patrick-kk的github,欢迎学习交流

    原文作者:PatrickZheng
    原文地址: https://blog.csdn.net/PatrickZheng/article/details/73458954
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞