zoukankan      html  css  js  c++  java
  • 爬虫1.6-selenium+HeadlessChrome

    爬虫-selenium+HeadlessChrome

    之前的笔记已经提到过selenium+chromedriver爬取Ajax技术加载的数据,但这种方式过于笨重,原因在于,每打开一个页面,都需要浏览器解析数据渲染界面,但实际上我们的爬虫不需要这些操作。所以一个没有界面但又完全可以模拟浏览器行为和获取与浏览器完全相同的数据就非常有意义,过去爬虫界流行的PhantomJS已经停止更新,并且新版的selenium目前已停止支持PhantomJS,所以现在替代方案为headless-Firefoxheadless-chrome(无头浏览器)

    不多BB,谷歌大法好。

    1. 浏览器处理步骤

    1)处理HTML脚本,生成DOM树
    2)处理CSS脚本,生成CSSOM树 (DOM和CSSOM是独立的数据结构)
    3)将DOM树和CSSOM树合并为渲染树
    4)对渲染树中的内容进行布局,计算每个节点的几何外观
    5)将渲染树中的每个节点绘制到屏幕中

    无头浏览器实际上节省了第4、5两个步骤。另外headeless-chrome还可以方便的实现并发,不多说了,直接上实战。

    2. headless-chrome初体验

    from selenium.webdriver.chrome.options import Options
    from selenium import webdriver
    import time
    
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # 基础设置
    chrome_options.add_argument('--disable-gpu')
    base_url = "https://www.baidu.com/"
    driver = webdriver.Chrome(executable_path=r'C:UsershelloworldDesktoppython_testchromedriver.exe',options=chrome_options)  # options必须设置,否则还是会打开界面
    
    driver.get(base_url)
    driver.find_element_by_id('kw').send_keys('python')
    click = driver.find_element_by_id('su')
    driver.execute_script('arguments[0].click()', click)
    time.sleep(3)  # 睡3秒是因为点击后需要等待一段时间,数据才会加载
    driver.save_screenshot('baidu.png')  # 从文件夹中打开baidu.png即可发现搜索python成功
    driver.close()
    

    因为现在爬虫的速度很快,前端的元素结构往往反应不过来,所以执行click操作时嵌入了JS脚本比较稳妥。

    3. 实战爬取淘宝镇、街道信息

    实际上无头浏览器的的代码操作与又界面的时候是完全一样的,唯一不同的是对无头浏览器的某些操作最好嵌入js代码执行,以防出现速度过快找不到元素。

    # encoding: utf-8
    
    '''
    Created on 2018年1月5日
    
    @author: wulinfeng@csdn博客
    @date: 2018-1-5
    '''
    
    import time
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    import pymysql
    
    
    def init_db():
        global CONNECTION
        CONNECTION = pymysql.connect("地址", "用户名", "密码", "数据库", use_unicode=True, charset="utf8")
    
    
    def init_web_driver():
        global DRIVER
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')
        DRIVER = webdriver.Chrome(executable_path=r'C:UsershelloworldDesktoppython_testchromedriver.exe',
                                  chrome_options=chrome_options)
    
    
    def close_db():
        CONNECTION.close()
    
    
    def close_web_driver():
        DRIVER.quit()
    
    
    def login_taobao(username, password):
        DRIVER.get("https://login.taobao.com/member/login.jhtml?spm=a21bo.2017.754894437.1.5af911d9fOuJW4&f=top&redirectURL=https%3A%2F%2Fwww.taobao.com%2F")
        # 选择登陆方式
        DRIVER.find_element_by_xpath("//div[@class='login-links']/a[1]").click()
    
        # 登陆
        input_user = DRIVER.find_element_by_xpath("//*[@id="TPL_username_1"]")
        input_user.clear()
        input_user.send_keys(username)
    
        DRIVER.find_element_by_xpath("//*[@id="TPL_password_1"]").send_keys(password)
        DRIVER.find_element_by_xpath("//*[@id="J_SubmitStatic"]").click()
        time.sleep(0.5)
    
    
    def get_data():
        # 点击地址选择
        # DRIVER.find_element_by_xpath("//*[@id="city-title"]").click()
        city_title = DRIVER.find_element_by_id("city-title")
        DRIVER.execute_script('arguments[0].click();', city_title)
    
        get_province_and_sub()
    
    
    def get_province_and_sub():
        # 获得省列表
        province_items = DRIVER.find_element_by_class_name("city-province").find_elements_by_tag_name("a")
    
        for province_item in province_items:
            pid = province_item.get_attribute("attr-id")
            pname = province_item.get_attribute("title")
            if pid == "-1":
                print("continue province")
                continue
    
            sql = "insert into region_province_t (province_id,province) values('" + pid + "','" + pname + "')"
            print(sql)
            cursor = CONNECTION.cursor()
            cursor.execute(sql)
            CONNECTION.commit()
    
            # province_item.click()
            DRIVER.execute_script('arguments[0].click();', province_item)
            time.sleep(0.5)
    
            get_city_and_sub(pid)
            back_tab(0)
    
    
    def get_city_and_sub(pid):
        # 获得市列表
        city_items = DRIVER.find_element_by_class_name("city-city").find_elements_by_tag_name("a")
        for city_item in city_items:
            cid = city_item.get_attribute("attr-id")
            cname = city_item.get_attribute("title")
            if cid == "-1":
                print("continue city")
                continue
    
            sql = "insert into region_city_t (city_id,city,province_id) values('" + cid + "','" + cname + "','" + pid + "')"
            print(sql)
            cursor = CONNECTION.cursor()
            cursor.execute(sql)
            CONNECTION.commit()
    
            # city_item.click()
            DRIVER.execute_script('arguments[0].click();', city_item)
            time.sleep(1)
    
            get_area_and_sub(cid)
            back_tab(1)
    
    
    def get_area_and_sub(cid):
        # 获得县区列表
        area_items = DRIVER.find_element_by_class_name("city-district").find_elements_by_tag_name("a")
        for area_item in area_items:
            aid = area_item.get_attribute("attr-id")
            aname = area_item.get_attribute("title")
            if aid == "-1":
                print("continue area")
                continue
    
            sql = "insert into region_area_t (area_id,area,city_id) values('" + aid + "','" + aname + "','" + cid + "')"
            print(sql)
            cursor = CONNECTION.cursor()
            cursor.execute(sql)
            CONNECTION.commit()
    
            # area_item.click()
            DRIVER.execute_script('arguments[0].click();', area_item)
            time.sleep(0.5)
    
            get_town_and_sub(aid)
            back_tab(2)
    
    
    def get_town_and_sub(aid):
        # 获得镇列表
        town_items = DRIVER.find_element_by_class_name("city-street").find_elements_by_tag_name("a")
        for town_item in town_items:
            tid = town_item.get_attribute("attr-id")
            tname = town_item.get_attribute("title")
            if tid == "-1":
                print("continue town")
                continue
    
            sql = "insert into region_town_t (town_id,town,area_id) values('" + tid + "','" + tname + "','" + aid + "')"
            print(sql)
            cursor = CONNECTION.cursor()
            cursor.execute(sql)
            CONNECTION.commit()
    
    
    def back_tab(index):
        districtEle = DRIVER.find_element_by_class_name("city-select-tab").find_elements_by_tag_name("a")[index]
        DRIVER.execute_script('arguments[0].click();', districtEle)
        time.sleep(0.5)
    
    
    if __name__ == '__main__':    
        init_db()
        init_web_driver()
        login_taobao("用户名", "密码")
        get_data()
        close_db()
        close_web_driver()
    

    作者:bitterz
    本文版权归作者和博客园所有,欢迎转载,转载请标明出处。
    如果您觉得本篇博文对您有所收获,请点击右下角的 [推荐],谢谢!
  • 相关阅读:
    ImageLightbox.js – 响应式的图片 Lightbox 插件
    精美素材:10套最新出炉的免费扁平图标下载
    盘点2013年那些最优秀的网页设计作品【系列三】
    12个带给你惊喜用户体验的手机界面设计
    一款效果精致的 jQuery 多层滑出菜单插件
    创意无限:20幅惊人的霓虹灯摄影照片欣赏
    『设计前沿』14款精致的国外 iOS7 图标设计示例
    2013年值得我们学习的网页设计作品【系列二】
    Summernote – 基于 Bootstrap 的文本编辑器
    『摄影欣赏』2013年微软必应搜索十大首页美图
  • 原文地址:https://www.cnblogs.com/bitterz/p/10195129.html
Copyright © 2011-2022 走看看