使用python+selenium爬取学生信息并入库

来源:互联网 发布:照片真假辨别软件 编辑:程序博客网 时间:2024/05/01 23:07

在学校的网站上发现了一些有趣的东西,就是能看到同年级的所有学院学生的信息。

该页面大概如下

于是好奇的我就打算把所有信息抓取下来。


一开始我打算使用 requests + BeautifulSoup 进行模拟爬取。但是因为上面的 “下一页” 是post一个form, 然后post的参数值需要从当前页面抓取,操作麻烦,而且到最后都没有成功。于是我就打算换一个工具,就选择了 selenium。

简单的介绍一下 selenium 吧。


selenium是一个web的自动化测试工具,和其它的自动化工具相比来说其最主要的特色是跨平台、跨浏览器。
支持windows、linux、MAC,支持ie、firefox、safari、opera、chrome等。
此外还有一个特色是支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器的执行,相当于分发机的功能。

但是我把他玩成了一个爬虫。。。


一个简单的例子:

测试例子:

from selenium import webdriverfrom selenium.common.exceptions import NoSuchElementExceptionfrom selenium.webdriver.common.keys import Keysimport timebrowser = webdriver.Firefox() # Get local session of firefoxbrowser.get("http://www.yahoo.com") # Load pageassert "Yahoo!" in browser.titleelem = browser.find_element_by_name("p") # Find the query boxelem.send_keys("seleniumhq" + Keys.RETURN)time.sleep(0.2)  # Let the page load, will be added to the APItry:    browser.find_element_by_xpath("//a[contains(@href,'http://seleniumhq.org')]")except NoSuchElementException:    assert 0, "can't find seleniumhq"browser.close()

下面是我的爬取操作

图中的table标签附近的源代码大概是这样子的

<div class="scontent">            <table width="100%" border="0" cellspacing="1" class="stable">                <tr>                    <td class="stdpic" width="20%">                        学号                    </td>                    <td class="stdpic" width="20%">                        姓名                    </td>                    <td class="stdpic" width="15%">                        性别                    </td>                    <td class="stdpic" width="25%">                        班级                    </td>                    <td class="stdpic" width="20%">                        操作                    </td>                </tr>...</table></div>

所以要找到这个 table 可以用一下代码
table = driver.find_element_by_class_name('scontent')
取到这个 table 后,就可以用 table.text 获取到 table 上的所有字符串

对这些字符串进行一定的分析后,就可以入库了


然后就是要实现 点击 “下一页 ”

“下一页”源代码如下:

<a id="ltNext" href="javascript:__doPostBack('ltNext','')">下一页</a>

可以看到是调用了一个js实现的 下一页 功能。要在 selenium 上实现js的模拟,用如下的代码:

js = r"__doPostBack('ltNext','')" driver.execute_script(js) # 执行js代码


完整的代码如下:

from selenium import webdriverfrom selenium.webdriver.common.keys import Keysfrom selenium.common.exceptions import TimeoutException, NoSuchElementExceptionimport mysql.connectordef crawler():driver = webdriver.Firefox() driver.set_page_load_timeout(10)driver.get(url) # 加载页面        conn = mysql.connector.connect(user='use', password='pwd', database='database', use_unicode=True)  # 数据库的连接        cursor = conn.cursor()</span><span style="font-size:18px;">         js = r"__doPostBack('ltNext','')" # “下一页” 的js源码for temp in range(626): # 626为页码数# 下面使用 try catch 的原因是加载的过快,很可能会找不到 table 这个标签,所以需要 sleep 一下后继续获取                try:table = driver.find_element_by_class_name('scontent')except NoSuchElementException:time.sleep(1)table = driver.find_element_by_class_name('scontent')finally:while table is None:time.sleep(0.1)driver.find_element_by_class_name('scontent')# 分析字符串的代码省略。。。                # data 保存一个 学号, 姓名, 性别, 学院 的 数据。                for data in datas:                         sql = r"insert into student (student_id, name, sex, department) values ('%s', '%s', '%s', '%s')" % (data[0], data[1], data[2], data[3])                        cursor.execute(sql)if temp != 625:driver.execute_script(js)        cursor.close()        conn.commit()        conn.close()        driver.close()







0 0