爬虫篇:动态网页的处理方式(下)——模拟浏览器行为

爬虫篇:动态网页的处理方式(下)——模拟浏览器行为

前言:

前面的例子中,我们使用WebKit库,可以自定义浏览器渲染引擎,这样就可以完全控制想要执行的行为。如果不需要那么高的灵活性,那么还有一个不错的替代品 Selenium 可以选择,它提供了使浏览器自动化的API 接口。


Selenium 简介:

Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持市面上几乎所有的主流浏览器。

本来打算使用的是selenium + PhantomJS的组合,但发现Chrome以及FireFox也相继推出无头 ( headless ) 浏览器模式,个人比较倾向Chrome。本文采用的是Selenium+Chrome的组合。


示例:

运用到爬虫中的思路是:

  • 使用Selenium 渲染网页,解析渲染后的网页源码,或者直接通过Selenium 接口获取页面中的元素。

还是以 新浪读书——书摘 这个网站为例,目标是获取列表中每篇文章详情页的地址,直接看示例代码:

# coding=utf-8

import time

from selenium import webdriver


class SinaBookSpider(object):

    # 创建可见的Chrome浏览器, 方便调试
    driver = webdriver.Chrome()

    # 创建Chrome的无头浏览器
    # opt = webdriver.ChromeOptions()
    # opt.set_headless()
    # driver = webdriver.Chrome(options=opt)

    driver.implicitly_wait(10)

    total = 1526  # 预先计算的总数据量
    count = 0  # 已爬取的数据量

    # 记录解析以及翻页位置
    location = 0
    click_times = 0

    def run(self):
        """
        开始爬虫
        :return:
        """
        # get方式打开网页
        self.driver.get("http://book.sina.com.cn/excerpt/rwws/")

        self.parselist()

        while self.count < self.total:
            if self.click_times is 2:

                self.driver.find_element_by_css_selector('#subShowContent1_page > span:nth-child(6) > a').click()

                # 等待页面加载完成
                time.sleep(5)
                self.click_times = 0
                self.location = 0
            else:
                self.driver.find_element_by_css_selector('#subShowContent1_loadMore').click()

                # 等待页面加载完成
                time.sleep(3)
                self.click_times += 1

            # 分析加载的新内容,从location开始
            self.parselist()

        self.driver.quit()

    def parselist(self):
        """
        解析列表
        :return:
        """
        divs = self.driver.find_elements_by_class_name("item")

        for i in range(self.location, len(divs)):
            link = divs[i].find_element_by_tag_name('a').get_attribute("href")
            print link

            self.location += 1
            self.count += 1
        print self.count


if __name__ == '__main__':
    spider = SinaBookSpider()
    spider.run()

代码地址:dynamic-web-process —— GitHub
如果你想实际运行上述代码,请在运行之前确定:安装了与浏览器版本对应的驱动,并正确的添加到了环境变量中。

  • 使用selenium时同样要特别注意的是如何确定 网页是否加载完成,有三种方式:

    • 强制等待
    • 隐形等待
    • 显性等待

有关这三种方式的讲解可以看这里:Python selenium —— 一定要会用selenium的等待,三种等待方式解读 —— 灰蓝的博客


总结:

到此,我们介绍了动态页面处理的两种思路:

做一下简单的比较:

  • 前者在运行上更快,开销更小。在实际情况中,大多数网页都可以被逆向,但是有些网页足够复杂逆向要花费极大的功夫。
  • 后者在思路上更直观,更容易被接受和理解。浏览器渲染引擎能够为我们节省了解网站后端工作原理的时间,但是渲染网页增大了开销,使其比单纯下载HTML更慢。另外,使用后者通常需要轮训网页来检查是否已经得到所需的HTML元素,这种方式非常脆弱,在网络较慢时经常会失败。

采用哪种方法,取决于爬虫活动中的具体情况:

  • 易于逆向、对速度和资源要求高的,应使用前者;
  • 难以逆向、没有工程上的优化的要求的,可以使用后者。

个人认为模拟浏览器的方法应尽量避免,因为浏览器环境对内存和CPU的消耗非常多,可以作为短期决绝方案,此时长期的性能和可靠性并不算重要;而作为长期解决方案,我会尽最大努力对网站进行逆向工程。


本文有什么错误或不足之处,欢迎指出!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值