• 爬虫:Selenium + PhantomJS


    更:Selenium特征过多(language/UserAgent/navigator/en-US/plugins),以Selenium打开的浏览器处于自测模式,很容易被检测出来,解决方法可选:

    1. 用mitmproxy拦截请求,在请求间修改框架特征。
    2. 手动修改自动化框架特征。
    3. 不改特征的话,用pyppeteer修改js代码中特征检测逻辑。
    4. 用其它webdriver。

    做爬虫two years,爬过网站数百上千,简单点的用lxml,xpath,css,re,解析源码、稍复杂点的数据用AJAX加载的、js加载的、源码数据加密的、再复杂限制cookies带cookie,封IP的上代理IP,出验证码的破解验证码,更复杂的携带参数加密的,略简单的对加密方式用python模拟解密,困难的用PyV8等方法执行加密js文件,各式各样反反爬手段

    这场恩恩怨怨了无尽头,对于异步加载数据的情况,可以抓包,也可以用Selenium + PhantomJS模拟浏览器,Selenium是一个用于Web应用程序测试的工具,它直接运行在浏览器中,就像真实的用户在操作一样。由于这个性质,Selenium也是一个强大的网络数据采集工具,可以获取异步加载技术的网页。

    安装方法请点击

    放一个爬淘宝的例子感受一下

    #encoding: utf-8
    '''
        使用selenium + PhantomJS 爬淘宝“男士手表”前100页,三四千个item
        存入MongoDB
        用到selenium:点击,清空,输入
    '''
    from selenium import webdriver
    from pymongo import MongoClient
    from lxml import etree
    
    # 实例化浏览器
    driver = webdriver.PhantomJS()
    # 窗口最大化
    driver.maximize_window()
    
    # 连接MongoDB数据库
    client = MongoClient('localhost',27017)
    taobao = client['test']['taobao']
    
    def scrapy_item(url, page):
        '''采集并写入MongoDB'''
        # 打开商品页
        driver.get(url)
        # 智能等待10s
        driver.implicitly_wait(10)
        sel = etree.HTML(driver.page_source)
        divs = sel.xpath('//div[@class="ctx-box J_MouseEneterLeave J_IconMoreNew"]')
        for x in divs:
            d = {}
            d["price"] = x.xpath('div[1]/div[1]/strong/text()')[0]
            d["counts"] = x.xpath('div[1]/div[2]/text()')[0]
            d["description"] = x.xpath('string(div[2]/a)').strip()
            d["shop"] = x.xpath('div[3]/div[1]/a/span[2]/text()')[0]
            # item写入MongoDB
            taobao.insert_one(d)
            print(d)
        if page < 100:
            # 少于100页,继续下一页
            page += 1
            # 传入参数是:当前页面URL,下页页码
            nextpage(driver.current_url, page)
    
    def nextpage(url, page):
        '''获得下一页连接并采集'''
        # 打开刚采集完毕的页面
        driver.get(url)
        # 智能等待10s
        driver.implicitly_wait(10)
        # 点击下一页
        driver.find_element_by_xpath('//a[@trace="srp_bottom_pagedown"]').click()
        driver.implicitly_wait(5)
        driver.get(driver.current_url)
        driver.implicitly_wait(10)
        # 得到下一页URL,继续采集
        scrapy_item(driver.current_url, page)
    
    if __name__ == '__main__':
        # 打开淘宝首页
        driver.get('https://www.taobao.com/')
        # 智能等待10s
        driver.implicitly_wait(10)
        # 找到搜索框,清空搜索框内容
        driver.find_element_by_id('q').clear()
        # 填入搜索条件
        driver.find_element_by_id('q').send_keys('男士手表')
        # 点击“搜索”
        driver.find_element_by_class_name('btn-search').click()
        # 搜索完毕,到达商品页面;拿着商品页面URL开始采集,页码初始化为1
        scrapy_item(driver.current_url, 1)


    使用前第一步先实例化浏览器,这里用PhantomJs,它是一种“无头”浏览器,开销小,速度快。另外还有Chrome,Firefox,用的比较少
    driver = webdriver.PhantomJS()
     

    第二步发请求,get()后的driver.page_source含有异步加载信息
    driver.get(url)

    第三步,打开一个网页肯定需要时间,webdriver有implicitly_wait(time)智能等待一段时间,超过time不等了,没到time但加载好了,也就不等了
    driver.implicitly_wait(10)
    第四步,锁定数据位置,有通过Id的,Xpath的,Css的,类名Class_name的,标签名tag_name的,等。
     
    第五步,有时异步数据是基于事件驱动的,例如当鼠标下拉到页面上某一位置时才加载数据,当点击某一处才加载数据。两种办法,一把鼠标移动到某个位置点击触发事件,二把鼠标移动到页面最下端触发事件后,再解析源码;知乎解答

    用Chrome()方法模拟浏览器

    打开出现data;不跳转网页的,需下载chrome浏览器驱动   下载地址  或更换Chrome版本,将下载好的chromedriver.exe 放在chrome安装目录下,并设置chrome路径到path环境变量中

    使用示例:

    # coding = utf-8
    from selenium import webdriver
    
    
    driver = webdriver.Chrome()
    driver.get('http://www.baidu.com')
    driver.close()
  • 相关阅读:
    vue组件常用传值
    定时器的暂停,继续,刷新
    element-ui表格带复选框使用方法及默认选中方法
    git创建分支
    CAS协议原理与代码实现(单点登录 与 单点登出的流程)
    Java-技术专区-Files类和Paths类的用法
    Java-技术专区-Java8特性-parallelStream
    ELK日志系统环境搭建-6.x系列
    Spring系列-Spring Aop基本用法
    Spring-框架系列-SpringIOC容器初始化
  • 原文地址:https://www.cnblogs.com/ldy-miss/p/6689767.html
Copyright © 2020-2023  润新知