使用slenium+chromedriver实现无敌爬虫

image.png

@概述
  • 通常各大网站的后台都会有一定的反爬机制,既为了数据安全,也为了减小服务器压力

  • 通常反爬的手段的方向,都是识别非浏览器客户端,而selenium所做的事情,恰恰是驱动真正的浏览器去执行请求和操作,只不过信号不是来源于鼠标,而是来源于selenium的API(selenium本是一个自动化的测试工具)

  • 自然人用户能做的一切,selenium几乎都驱动浏览器取做,无论是否有界面,包括输入、点击、滑动,等等

  • 然而到底是鼠标操作的浏览器发起的请求还是API,对于服务端来说,是没有任何差别的

@一些掌故
  • 早些的时候流行的组合并不是selenium+chrome浏览器驱动,而是selenium+phantomjs
    phantomjs是一款没有界面的浏览器,业界称作无头浏览器(headless),由于没有界面和渲染,其运行速度要大大优于有界面的浏览器,这恰恰是爬虫喜欢的,因此红极一时

  • 后来chrome和火狐推出了无头模式,且运行速度很流畅,phantomjs已然寿终正寝,因此我们表过不提

@开发环境的搭建(本文在windows下)
  • 安装selenium:pip install selenium
  • 接着我们还要下载浏览器驱动
浏览器 对应驱动下载链接
Chrome https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox https://github.com/mozilla/geckodriver/releases
Safari https://webkit.org/blog/6900/webdriver-support-in-safari-10/
@配置环境
image.png
@导包
# 导入selenium的浏览器驱动接口
from selenium import webdriver

# 要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys import Keys

# 导入chrome选项
from selenium.webdriver.chrome.options import Options
@第一个程序:抓取页面内容,生成页面快照
# 创建chrome浏览器驱动,无头模式(超爽)
options = Options()
ptions.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=chrome_options)

# 加载百度页面
driver.get("http://www.baidu.com/")
# time.sleep(3)

# 获取页面名为wrapper的id标签的文本内容
data = driver.find_element_by_id("wrapper").text
print(data)

# 打印页面标题 "百度一下,你就知道"
print(driver.title)

# 生成当前页面快照并保存
driver.save_screenshot("baidu.png")

# 关闭浏览器
driver.quit()
@模拟用户输入和点击搜索,跟真人操作一样!
    # get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择 time.sleep(2)
    driver.get("http://www.baidu.com/")

    # id="kw"是百度搜索输入框,输入字符串"程序猿"
    driver.find_element_by_id("kw").send_keys(u"程序猿")

    # id="su"是百度搜索按钮,click() 是模拟点击
    driver.find_element_by_id("su").click()
    time.sleep(3)

    # 获取新的页面快照
    driver.save_screenshot("程序猿.png")

    # 打印网页渲染后的源代码
    print(driver.page_source)

    # 获取当前页面Cookie
    print(driver.get_cookies())

    # ctrl+a 全选输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')

    # ctrl+x 剪切输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

    # 输入框重新输入内容
    driver.find_element_by_id("kw").send_keys("美女")

    # 模拟Enter回车键
    driver.find_element_by_id("su").send_keys(Keys.RETURN)
    time.sleep(3)

    # 清除输入框内容
    driver.find_element_by_id("kw").clear()

    # 生成新的页面快照
    driver.save_screenshot("美女.png")

    # 获取当前url
    print(driver.current_url)

    # 关闭浏览器
    driver.quit()
@模拟用户登录
    # 加载微博登录页
    driver.get("http://passport.weibo.cn/signin/login?entry=mweibo&r=http%3A%2F%2Fweibo.cn%2F&backTitle=%CE%A2%B2%A9&vt=")
    time.sleep(3)

    # 找到输入框,键入用户名和密码
    driver.find_element_by_id('loginName').send_keys("worio.hainan@163.com")
    driver.find_element_by_id('loginPassword').send_keys("Qq94313805")

    # 点击登录按钮
    driver.find_element_by_id('loginAction').click()
    time.sleep(3)

    # 快照显示已经成功登录
    print(driver.save_screenshot('jietu.png'))
    driver.quit()
@使用cookies登录
    # 加载知乎主页,查看快照知此时处于未登录状态
    driver.get("https://www.zhihu.com")
    time.sleep(1)
    print(driver.save_screenshot("zhihu_nocookies.png"))

    # 操作浏览器登录知乎并抓包cookies
    zhihu_cookies = {
        # 'aliyungf_tc' : 'AQAAAAR4YFOeswAAnLFJcVRd4MKOTTXu',
        'l_n_c': '1',
        'q_c1': '8572377703ba49138d30d4b9beb30aed|1514626811000|1514626811000',
        'r_cap_id': 'MTc5M2Y0ODUzMjc0NDMzNmFkNTAzZDBjZTQ4N2EyMTc=|1514626811|a97b2ab0453d6f77c6cdefe903fd649ee8531807',
        'cap_id': 'YjQyZTEwOWM4ODlkNGE1MzkwZTk3NmI5ZGU0ZTY2YzM=|1514626811|d423a17b8d165c8d1b570d64bc98c185d5264b9a',
        'l_cap_id': 'MGE0NjFjM2QxMzZiNGE1ZWFjNjhhZmVkZWQwYzBkZjY=|1514626811|a1eb9f2b9910285350ba979681ca804bd47f12ca',
        'n_c': '1',
        'd_c0': 'AKChpGzG6QyPThyDpmyPhXaV-B9_IYyFspc=|1514626811',
        '_xsrf': 'ed7cbc18-03dd-47e9-9885-bbc1c634d10f',
        'capsion_ticket': '2|1:0|10:1514626813|14:capsion_ticket|44:NWY5Y2M0ZGJiZjFlNDdmMzlkYWE0YmNjNjA4MTRhMzY=|6cf7562d6b36288e86afaea5339b31f1dab2921d869ee45fa06d155ea3504fe1',
        '_zap': '3290e12b-64dc-4dae-a910-a32cc6e26590',
        'z_c0': '2|1:0|10:1514626827|4:z_c0|92:Mi4xYm4wY0FRQUFBQUFBb0tHa2JNYnBEQ1lBQUFCZ0FsVk5DNjAwV3dCb2xMbEhxc1FTcEJPenpPLWlqSS1qNm5KVEFR|d89c27ab659ba979a977e612803c2c886ab802adadcf70bcb95dc1951bdfaea5',
        '__utma': '51854390.2087017282.1514626889.1514626889.1514626889.1',
        '__utmb': '51854390.0.10.1514626889',
        '__utmc': '51854390',
        '__utmz': '51854390.1514626889.1.1.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/',
        '__utmv': "51854390.100--|2=registration_date=20150408=1'3=entry_date=20150408=1",
    }

    # 将用户登录产生的cookies全部添加到当前会话
    for k, v in zhihu_cookies.items():
        driver.add_cookie({'domain': '.zhihu.com', 'name': k, 'value': v})

    # 再次访问知乎主页并拍照,此时已经是登录状态了
    driver.get("https://www.zhihu.com")
    time.sleep(3)
    print(driver.save_screenshot("zhihu_cookies.png"))

    # 退出浏览器
    driver.quit()
@模拟滚动条的滚动(这个用常规的爬虫很难实现)
    # 加载知乎主页
    driver.get("https://www.zhihu.com")
    time.sleep(1)

    # 加载本地cookies实现登录
    for k, v in zhihu_cookies.items():
        driver.add_cookie({'domain': '.zhihu.com', 'name': k, 'value': v})

    # 以登录状态再次发起访问
    driver.get("https://www.zhihu.com")
    time.sleep(3)

    # 将页面滚动到最后,执行多次
    for i in range(3):
        js = "var q=document.documentElement.scrollTop=10000"
        driver.execute_script(js)
        time.sleep(3)

    # 截图并退出,页面侧边滚动条已经下滑了许多像素
    print(driver.save_screenshot("zhihu_scroll.png"))
    driver.quit()
@一边滚动一边加载
  • 唯品会首页的女装图片,是一边滚动一边进行ajax异步加载的
  • 这个靠常规的抓包实现起来很麻烦
  • 使用selenium我们只需模拟用户多次下拉滚动条,一段时间之后再重新拿取渲染好的页面源码,就可以像爬取静态页面那样去爬取图片了
  • 类似这种操作,其实质就是开挂,是几乎无法防守的
    # 唯品会女装图片链接无法直接获得
    # 请求唯品会页面
    driver.get("https://category.vip.com/search-3-0-1.html?q=3|30036||&rp=30074|30063&ff=women|0|2|2&adidx=1&f=ad&adp=65001&adid=326630")
    time.sleep(3)

    # 逐渐滚动浏览器窗口,令ajax逐渐加载
    for i in range(1, 10):
        js = "var q=document.body.scrollTop=" + str(500 * i)  # PhantomJS
        js = "var q=document.documentElement.scrollTop=" + str(500 * i)  # 谷歌 和 火狐

        driver.execute_script(js)
        print('=====================================')
        time.sleep(3)

    # 拿到页面源码
    html = etree.HTML(driver.page_source)
    all_img_list = []

    # 得到所有图片
    img_group_list = html.xpath("//img[contains(@id,'J_pic')]")
    # img_group_list = html.xpath("//img[starts-with(@id,'J_pic')]")
    # 正则表达式匹配
    # img_group_list = html.xpath(r'//img[re:match(@id, "J_pic*")]',namespaces={"re": "http://exslt.org/regular-expressions"})

    # 收集所有图片链接到列表
    for img_group in img_group_list:
        img_of_group = img_group.xpath(".//@data-original | .//@data-img-back | .//@data-img-side")
        print(img_of_group)
        all_img_list.append('\n'.join(img_of_group) + '\n')

    # 将收集到的数据写入文件
    with open('vip.txt', 'w', encoding='utf-8') as f:
        f.write('\n'.join(all_img_list))

    # 退出浏览器
    driver.quit()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358