Python爬虫实战:使用Selenium抓取QQ空间好友说说
前面我们接触到的,都是使用requests+BeautifulSoup组合对静态网页进行请求和数据解析,若是JS生成的内容,也介绍了通过寻找API借口来获取数据。
但是有的时候,网页数据由JS生成,API借口又死活找不着或者是API借口地址随机变换,时间不等人。那就只能使用Selenium了。
一、Selenium简介
Selenium是一个用于Web应用的功能自动化测试工具,Selenium 直接运行在浏览器中,就像真正的用户在操作一样。
由于这个性质,Selenium也是一个强大的网络数据采集工具,其可以让浏览器自动加载页面,获取需要的数据,甚至页面截图,或者是判断网站上某些动作是否发生。
Selenium自己不带浏览器,需要配合第三方浏览器来使用。支持的浏览器有Chrome、Firefox、IE、Phantomjs等。
如果使用Chrome、FireFox或IE,我们可以看得到一个浏览器的窗口被打开、打开网站、然后执行代码中的操作。
但是,让程序在后台中运行更符合我们爬虫的气质,所以自己多使用Phantomjs作为浏览器载体,本篇文章也以Phantomjs作介绍
Phantomjs是一个“无头”浏览器,也就是没有界面的浏览器,但是功能与普通的浏览器无异。
二、在Python中使用Selenium获取QQ空间好友说说
之前使用pip安装好了selenium,直接在代码中import即可。
下面我们以一个实际的例子——获取一个QQ空间好友的说说信息,来简单讲解一下Selenium+Phantomjs的使用。
我们需要爬取的页面时这样的:
QQ空间好友说说的链接为:http://user.qzone.qq.com/{好友QQ号}/311我们抓取他发的说说的时间和内容。
python3运行代码
- 依旧先上代码:
# -*- coding:utf-8 -*- from bs4 import BeautifulSoup from selenium import webdriver import time # #使用Selenium的webdriver实例化一个浏览器对象,在这里使用Phantomjs # driver = webdriver.PhantomJS(executable_path=r"D:\phantomjs-2.1.1-windows\bin\phantomjs.exe") # #设置Phantomjs窗口最大化 # driver.maximize_window() # 登录QQ空间 def get_shuoshuo(qq): chromedriver = r"D:\soft\chromedriver_win32\chromedriver.exe" driver = webdriver.Chrome(chromedriver) #使用get()方法打开待抓取的URL driver.get('http://user.qzone.qq.com/{}/311'.format(qq)) time.sleep(5) #等待5秒后,判断页面是否需要登录,通过查找页面是否有相应的DIV的id来判断 try: driver.find_element_by_id('login_div') a = True except: a = False if a == True: #如果页面存在登录的DIV,则模拟登录 driver.switch_to.frame('login_frame') driver.find_element_by_id('switcher_plogin').click() driver.find_element_by_id('u').clear() # 选择用户名框 driver.find_element_by_id('u').send_keys('QQ号码') driver.find_element_by_id('p').clear() driver.find_element_by_id('p').send_keys('QQ密码') driver.find_element_by_id('login_button').click() time.sleep(3) driver.implicitly_wait(3) #判断好友空间是否设置了权限,通过判断是否存在元素ID:QM_OwnerInfo_Icon try: driver.find_element_by_id('QM_OwnerInfo_Icon') b = True except: b = False #如果有权限能够访问到说说页面,那么定位元素和数据,并解析 if b == True: driver.switch_to.frame('app_canvas_frame') content = driver.find_elements_by_css_selector('.content') stime = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail') for con, sti in zip(content, stime): data = { 'time': sti.text, 'shuos': con.text } print(data) pages = driver.page_source soup = BeautifulSoup(pages, 'lxml') #尝试一下获取Cookie,使用get_cookies() cookie = driver.get_cookies() cookie_dict = [] for c in cookie: ck = "{0}={1};".format(c['name'], c['value']) cookie_dict.append(ck) i = '' for c in cookie_dict: i += c print('Cookies:', i) print("==========完成================") driver.close() driver.quit() if __name__ == '__main__': get_shuoshuo('好友QQ号码')
获取到的数据截图如下:
三、代码简析
1.照例,导入需要使用的模块:
from bs4 import BeautifulSoup from selenium import webdriver import time
2.使用Selenium的webdriver实例化一个浏览器对象,在这里使用Phantomjs:
driver = webdriver.PhantomJS(executable_path="D:\\phantomjs.exe")
3.设置Phantomjs窗口最大化:
driver.maximize_window()
4.主函数部分
使用get()方法打开待抓取的URL:
driver.get('http://user.qzone.qq.com/{}/311'.format(qq))
等待5秒后,判断页面是否需要登录,通过查找页面是否有相应的DIV的id来判断:
try: driver.find_element_by_id('login_div') a = True except: a = False
如果页面存在登录的DIV,则模拟登录:
driver.switch_to.frame('login_frame') #切换到登录ifram driver.find_element_by_id('switcher_plogin').click() driver.find_element_by_id('u').clear()#选择用户名框 driver.find_element_by_id('u').send_keys('QQ号') driver.find_element_by_id('p').clear()#选择密码框 driver.find_element_by_id('p').send_keys('QQ密码') driver.find_element_by_id('login_button').click()#点击登录按钮 time.sleep(3)
接着,判断好友空间是否设置了权限,通过判断是否存在元素ID:QM_OwnerInfo_Icon
try: driver.find_element_by_id('QM_OwnerInfo_Icon') b = True except: b = False
如果有权限能够访问到说说页面,那么定位元素和数据,并解析:
if b == True: driver.switch_to.frame('app_canvas_frame') content = driver.find_elements_by_css_selector('.content') stime = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail') for con,sti in zip(content,stime): data = { # 'qq':qq, 'time':sti.text, 'shuos':con.text } print(data)
除了在Selenium中解析数据,我们还可以将当前页面保存为源码,再使用BeautifulSoup来解析:
pages = driver.page_source soup = BeautifulSoup(pages,'lxml')
最后,我们尝试一下获取Cookie,使用get_cookies():
cookie = driver.get_cookies() cookie_dict = [] for c in cookie: ck = "{0}={1};".format(c['name'],c['value']) cookie_dict.append(ck) i = '' for c in cookie_dict: i += c print('Cookies:',i)
另外,再介绍两个Selenium的常用方法:
- 保存屏幕截图:
driver.save_screenshot('保存的文件路径及文件名')
- 执行JS脚本:
driver.execute_script("JS代码")
对于Selenium更加详细的操作和使用,推荐一本书《selenium webdriver(python)第三版》网上可以搜索到;
Python爬虫实战:使用Selenium抓取QQ空间好友说说的更多相关文章
- Python爬虫实战四之抓取淘宝MM照片
原文:Python爬虫实战四之抓取淘宝MM照片其实还有好多,大家可以看 Python爬虫学习系列教程 福利啊福利,本次为大家带来的项目是抓取淘宝MM照片并保存起来,大家有没有很激动呢? 本篇目标 1. ...
- Python爬虫实战六之抓取爱问知识人问题并保存至数据库
大家好,本次为大家带来的是抓取爱问知识人的问题并将问题和答案保存到数据库的方法,涉及的内容包括: Urllib的用法及异常处理 Beautiful Soup的简单应用 MySQLdb的基础用法 正则表 ...
- Python爬虫实战一之爬取QQ音乐
一.前言 前段时间尝试爬取了网易云音乐的歌曲,这次打算爬取QQ音乐的歌曲信息.网易云音乐歌曲列表是通过iframe展示的,可以借助Selenium获取到iframe的页面元素, 而QQ音乐采用的是 ...
- [Python爬虫] 之四:Selenium 抓取微博数据
抓取代码: # coding=utf-8import osimport refrom selenium import webdriverimport selenium.webdriver.suppor ...
- 一次Python爬虫的修改,抓取淘宝MM照片
这篇文章是2016-3-2写的,时隔一年了,淘宝的验证机制也有了改变.代码不一定有效,保留着作为一种代码学习. 崔大哥这有篇>>小白爬虫第一弹之抓取妹子图 不失为学python爬虫的绝佳教 ...
- Python爬虫实战二之爬取百度贴吧帖子
大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...
- Python爬虫实战一之爬取糗事百科段子
大家好,前面入门已经说了那么多基础知识了,下面我们做几个实战项目来挑战一下吧.那么这次为大家带来,Python爬取糗事百科的小段子的例子. 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把 ...
- 转 Python爬虫实战二之爬取百度贴吧帖子
静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 ...
- 转 Python爬虫实战一之爬取糗事百科段子
静觅 » Python爬虫实战一之爬取糗事百科段子 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致 ...
随机推荐
- 关于masm中PTR伪指令的一点思考
在masm中,PTR伪指令只能修饰内存变量类型,因为任何寄存器的大小都是已知的且不能改变的(如果PTR修饰的是寄存器,则它修饰的是寄存器本身而不是其指向的内容)所以不能用PTR改变寄存器的大小,例如: ...
- Mac OS X下让ruby支持tcl/tk
我记得在老早在OS X10.8下使用ruby1.9.x的时候只要到下载安装ActiveTcl8.5,没怎么配置就运行tk好好的.但是近日想重新执行下tk代码,发现在require 'tk'的时候就报错 ...
- 十六进制颜色转换为iOS可以用的UIColor
// // UIColor+Transformation.h // ContactApp // // Created by 袁冬冬 on 15/9/11. // Copyright (c) 2 ...
- 2T以上的盘怎么分区, 利用parted创建 linuxTB硬盘GPT分区
parted创建GPT分区(fdisk不支持创建GPT分区,GPT支持大于2TB分区,MBR不支持) 介绍2种分区表: MBR分区表:(MBR含义:主引导记录) 所支持的最大卷:2T (T; tera ...
- 【读书笔记】C++Primer---第三章
1.由于为了与C语言兼容,字符串字面值与标准库string类型不是同一种类型: 2.以下代码中,cin有几点需要注意:a.读取并忽略开头所有的空白字符(如空格.换行符.制表符):b.读取字符直至再次遇 ...
- (译) JSON-RPC 2.0 规范(中文版)
http://wiki.geekdream.com/Specification/json-rpc_2.0.html 起源时间: 2010-03-26(基于2009-05-24版本) 更新: 2013- ...
- html居中定位
<!DOCTYPE html PUBLIC "-//W3C//Ddiv XHTML 1.0 divansitional//EN" "http://www.w3.or ...
- 一文读懂 Spring Boot、微服务架构和大数据治理三者之间的故事
微服务架构 微服务的诞生并非偶然,它是在互联网高速发展,技术日新月异的变化以及传统架构无法适应快速变化等多重因素的推动下诞生的产物.互联网时代的产品通常有两类特点:需求变化快和用户群体庞大,在这种情况 ...
- 我的Python之旅第二天
一 .字符串操作 1单引号('').双引号("").三引号(""" """)的区别. 如果字符串中不包含单引号.双引号, ...
- 字符串转json以及获取域名的参数
本例将通过location.search来进行字符串拼接成json以及查询域名参数的value console.log(request('id')); function request(obj){ v ...