C#使用Selenium实现QQ空间数据抓取 登录QQ空间
经@吃西瓜的星星提醒
首先我们介绍下Selenium
Selenium也是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Mozilla Suite等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建衰退测试检验软件功能和用户需求。支持自动录制动作和自动生成。Net、Java、Perl等不同语言的测试脚本。Selenium 是ThoughtWorks专门为Web应用程序编写的一个验收测试工具。
详细介绍点击这里
这里我们就利用模拟真人操作,不会被TX和谐来进行访问和数据抓取
这里用到的IDE是VS2017,系统Win10,浏览器驱动选择的是ChromeDriver
新建单元测试解决方案
安装Nuget包
我这里使用谷歌浏览器采集数据,所以就使用谷歌浏览器的驱动了,如果不喜欢谷歌浏览器的可以引用别的驱动程序包
命令
Install-Package Selenium.WebDriver
Install-Package Selenium.WebDriver.ChromeDriver
或者直接管理器安装 如下图
Selenium.WebDriver.ChromeDriver是在项目编译后将Chorme的驱动程序即ChormeDriver.exe程序复制到bin目录下,
NetCore则是复制到对应的netcoreappv文件目录下
这样基本引用就完成了,下面讲具体实现
首先创建一个测试类Qzone.cs,我们后面所有调用都在测试类中测试和实现
public class QzoneTest { [Fact] public void QQLogin() { var driver = new ChromeDriver(); driver.Url = "https://qzone.qq.com/"; driver.Quit(); } }
因为是xUnit测试类,所以可以直接右键调试测试,运行起来可以看到下图
驱动程序会自动打开Chrome浏览器,并且调转到指定的页面.
空间页面已经打开了,下面就是登录步骤了
登录有两种方法,也是QQ自己提供的
第一种 如果有已经登陆的QQ,直接点击头像就可以登录
第二种 输入账号密码登录
下面我们来详细介绍
先说第二种,第一种比较简单,第二种学会之后,第一种就so easy了
我们需要找到文本框 输入账号和密码
这里我们就用到了Selenium查找元素的方法了
这里给我们提供了很多查找元素的方法,根据名字我们就能明白它的意思
var driver = new ChromeDriver(); driver.FindElement(); driver.FindElementByClassName(); driver.FindElementByCssSelector(); driver.FindElementById(); driver.FindElementByName(); driver.FindElementByTagName(); driver.FindElementByXPath()
我们使用ByXPath方法来查找元素,XPath的详细介绍可以自行了解下,我这里只给大家介绍如何快速查找XPath
刚才打开的空间地址,找到文本框,然后检查元素,右侧元素位置右键->Copy->Copy XPath
可以得到这样一个地址
//*[@id="u"]
同样的方法找到密码框
//*[@id="p"]
通过这个xpath我们可以找到用户名的xpath路径,然后在程序里面这样写
try { var userName = driver.FindElementByXPath("//*[@id='u']"); //这里的userName就是用户名的文本框 //设置用户名的值 userName.SendKeys("123456"); var pwd = driver.FindElementByXPath("//*[@id='p']"); pwd.SendKeys("********"); } finally { driver.Quit(); }
运行后出现异常
不要慌,这个是因为浏览器驱动没有找到元素导致的,我们来仔细检查一下
原来文本框是嵌套在一个Iframe中的,怪不得当前驱动程序无法找到元素,因为当前驱动只会找到当前连接下的元素,嵌套元素不包含在内
那么我们就用到了切换语法
try { //切换语法有两种,一种是根据索引切换,另外一种根据iframe名称切换 //这里我们使用name切换 ITargetLocator tagetLocator = driver.SwitchTo(); //tagetLocator.Frame(1); //frame index. tagetLocator.Frame("login_frame"); //frame frame name. var userName = driver.FindElementByXPath("//*[@id='u']"); //这里的userName就是用户名的文本框 //设置用户名的值 userName.SendKeys("123456"); var pwd = driver.FindElementByXPath("//*[@id='p']"); pwd.SendKeys("********"); } finally { driver.Quit(); }
然后调试测试,如下图
这样就把值填写到文本框中了
最后就是点击登录了,找到登录按钮元素,Click it 同样的方式找到登录按钮元素 并且点击
[Fact] public void QQLogin() {
dynamic type = (new PictureTest()).GetType(); string currentDirectory = Path.GetDirectoryName(type.Assembly.Location); var driver = new ChromeDriver(currentDirectory); driver.Url = "https://qzone.qq.com/"; try { //切换语法有两种,一种是根据索引切换,另外一种根据iframe名称切换 //这里我们使用name切换 ITargetLocator tagetLocator = driver.SwitchTo(); //tagetLocator.Frame(1); //frame index. tagetLocator.Frame("login_frame"); //frame frame name. var userName = driver.FindElementByXPath("//*[@id='u']"); //这里的userName就是用户名的文本框 //设置用户名的值 userName.SendKeys("123456"); var pwd = driver.FindElementByXPath("//*[@id='p']"); pwd.SendKeys("********"); var btnLogin = driver.FindElementByXPath("//*[@id='login_button']"); //这里是判断登录按钮是否可见,可以不写,直接调用click方法 if (btnLogin != null && btnLogin.Displayed == true) { btnLogin.Click(); } } finally { driver.Quit(); } }
然后就登录成功了
做一下总结,用到的几个关键语法
//Iframe切换,如果需要捕获的元素不在当前页面,则找到嵌套页面进行切换 //切换语法有两种,一种是根据索引切换,另外一种根据iframe名称切换 ITargetLocator tagetLocator = driver.SwitchTo(); //tagetLocator.Frame(1); //frame index. tagetLocator.Frame("login_frame"); //frame frame name. //查找元素方法,可以使用css定位 var userName = driver.FindElementByXPath("//*[@id='u']"); //设置文本框的值SendKeys userName.SendKeys("123456"); //元素点击事件 var btnLogin = driver.FindElementByXPath("//*[@id='login_button']"); btnLogin.Click();
只要了解下驱动程序操作浏览器的一些方法就可以自己摸索实现想要的东西,比如点击切换登录框和快捷登录
比如找到相册元素并点击,找到菜单说说元素并点击,设置文本框值,发说说,写留言 都可以摸索使用
登录先讲到这里,改天写一下说说或者留言板,或者相册图片的保存
git 源码地址:https://github.com/ermpark/CrawlingQzone