首页 > 代码库 > 动态网页爬取
动态网页爬取
四六级成绩查询网站我所知道的有两个:学信网(http://www.chsi.com.cn/cet/)和99宿舍(http://cet.99sushe.com/),这两个网站采用的都是动态网页。我使用的是学信网,好了,网站截图如下:
网站的代码如下:
- 1 <form method="get" name="form1" id="form1" action="/cet/query">
- 2
- 3 <table border="0" align="center" cellpadding="0" cellspacing="0">
- 4 <tr><td align="right">准考证号:</td><td align="left"><input name="zkzh" value="112008000463141" id="zkzh" type="text" size="18" maxlength="15" class="input_text input_t_l" /></td>
- 5 <td align="left" class="font12 color666">请输入15位准考证号</td>
- 6 </tr>
- 7 <tr><td align="right">姓名:</td><td align="left"><input name="xm" value="啊啊" id="xm" type="text" size="18" maxlength="50" class="input_text input_t_l" /></td>
- 8 <td align="left" class="font12 color666">姓名超过3个字,可只输入前3个</td>
- 9 </tr>
- 10
- 11 <tr><td align="center"> </td>
- 12 <td colspan="2" align="left"><input type="submit" id="submitCET" class="btn_blue" value="查询" /></td>
- 13 </tr>
- 14 </table>
- 15 </form>
由图中可以看出表单提交的链接为/cet/query,即:http://www.chsi.com.cn/cet/query,好了,填写表单和结果如下:
但是,点击查看源代码之后发现,没有成绩,即代码仍是上面那个,之后按F12查看代码:
- 1 <TBODY><TR>
- 2 <TH>姓名:</TH>
- 3 <TD>XXXX</TD></TR>
- 4 <TR>
- 5 <TH>学校:</TH>
- 6 <TD>XXXXXX</TD></TR>
- 7 <TR>
- 8 <TH>考试类别:</TH>
- 9 <TD>英语四级</TD></TR>
- 10 <TR>
- 11 <TH>准考证号:</TH>
- 12 <TD>120135151100101</TD></TR>
- 13 <TR>
- 14 <TH>考试时间:</TH>
- 15 <TD>2015年06月</TD></TR>总分:</TH><TD class=fontBold vAlign="top"><SPAN class=colorRed>403 </SPAN><BR><SPAN class=color666>听力:</SPAN> 132 <BR><SPAN class=color666>阅读:</SPAN> 147 <BR><SPAN class=color666>写作与翻译:</SPAN> 124 </TD></TR>
该代码显示了成绩,可以知道,该网站使用的是动态网页,用的JavaScript或者Ajax.js还是其他的我就不知道了0.0。上面为需求。
前言:使用过BeautifulSoup爬取过,但是BeautifulSoup是爬取不了动态网页的,上各种论坛找各种资料,用了n种东西,scapy,pyqt等等,走了真心不少弯路,不是不行,应该是我不会用,最终用了selenium和phantomjs,这两个应该也是目前最流行的爬虫模块了吧。
一、导入selenium和phantomjs
- 1 from selenium import webdriver
- 2
- 3 driver = webdriver.PhantomJS(executable_path=‘D:\phantomjs-2.1.1-windows\phantomjs.exe‘)
- 4 driver.get(url)
- 5 driver.find_element_by_id(‘zkzh‘).send_keys(i)
- 6 driver.find_element_by_id(‘xm‘).send_keys(xm)
- 7 driver.find_elements_by_tag_name(‘form‘)[1].submit()
代码说明:
3.selenium可以加载很多驱动,比如Chrome、FireFox等,这里需要有这两个浏览器和驱动才行,折腾了一下,网上说Phantomjs是较好的了
5、6、7分别是准考证号,姓名和提交
二、字符处理
提交之后就可以直接查找了:
- 1 print driver.find_element_by_xpath("//tr[3]/td[1]").text
- 2 print driver.find_element_by_xpath("//tr[6]/td[1]").text
代码说明:
1.查看姓名
2.查看分数及其具体成绩
打印之后为:
- 姓名
- 403
- 听力
- 132
- 阅读
- 147
- 写作
- 142
之后要对分数进行字符串处理,选取各部分的数字,这里我们采用re模块:
- 1 import re
- 2 m = re.findall(r‘(\w*[0-9]+)\w*‘, chuli2)
其中m是数组,输出的是["403","132","147","142"]
三、数据库
我们学校也不知说很渣还是人性化,反正公布了全校的四六级准考证号,当然,是excel的,需要导入mysql数据库,打开Excel之后,我发现微软大法和Oracle真是牛逼啊,Excel365居然有mysql workbench连接部分
数据库代码如下:
- 1 import MySQLdb
- 2
- 3 conn = MySQLdb.Connect(host=‘localhost‘, user=‘root‘, passwd=‘root‘, db=‘cet‘, port=3306, charset=‘utf8‘)
- 4 cur = conn.cursor()
- 5 curr = conn.cursor()
- 6 cur.execute("select name from cet.cet where zkzh=(%s)" % i)
- 7 xm = cur.fetchone()[0]
- 8 print "Name is " + xm
- 9 sqltxt = "update cet.cet set leibie=(%s),zongfen=(%s),tingli=(%s),yuedu=(%s),xiezuo=(%s) WHERE zkzh=(%s)" % (
- 10 ss, m[0], m[1], m[2], m[3], i)
- 11 cur.execute(sqltxt)
- 12 conn.commit()
- 13 cur.close()
- 14 conn.close()
代码说明:
3.python连接数据库代码
6.连接数据库取得姓名部分
9.这行我好无语啊,使用‘“+ss+”’这样的写法一直报错,最终找了半天资料,这个写法我不太喜欢,但是凑合着用吧。
12.记得一定要提交事务!!!commit()!!!不然是没有效果的
四、使用代理服务器(保留以后写)
运行了一段时间之后,大概抓了几百人的吧,然后就出现要求验证码了,解决办法只能处理验证码或者使用代理服务器了,这部分继续加强学习再弄出来了↖(^ω^)↗
五、源代码和效果
- 1 # encoding=utf8
- 2
- 3 import MySQLdb
- 4 import re
- 5 import time
- 6
- 7 from selenium import webdriver
- 8
- 9 # connect mysql,get zkxh and xm
- 10 conn = MySQLdb.Connect(host=‘localhost‘, user=‘root‘, passwd=‘root‘, db=‘cet‘, port=3306, charset=‘utf8‘)
- 11 cur = conn.cursor()
- 12 curr = conn.cursor()
- 13 url = ‘http://www.chsi.com.cn/cet/query‘
- 14
- 15
- 16 def kaishi(i):
- 17 print i,
- 18 print " start"
- 19 try:
- 20 cur.execute("select name from cet.cet where zkzh=(%s)" % i)
- 21 xm = cur.fetchone()[0]
- 22 print "Name is " + xm
- 23 driver = webdriver.PhantomJS(executable_path=‘D:\phantomjs-2.1.1-windows\phantomjs.exe‘)
- 24 driver.get(url)
- 25 driver.find_element_by_id(‘zkzh‘).send_keys(i)
- 26 driver.find_element_by_id(‘xm‘).send_keys(xm)
- 27 driver.find_elements_by_tag_name(‘form‘)[1].submit()
- 28 driver.set_page_load_timeout(10)
- 29 leibie = driver.find_element_by_xpath("//tr[3]/td[1]").text
- 30 leibie2 = str(leibie.encode("utf-8"))
- 31 ss = ""
- 32 if leibie2.decode("utf-8") == ‘英语四级‘.decode("utf-8"):
- 33 ss = 4
- 34 else:
- 35 ss = 6
- 36 # zongfen = driver.find_element_by_xpath("//tr[6]/th[1]").text
- 37 # print zongfen
- 38 # print "===="
- 39 chuli = driver.find_element_by_xpath("//tr[6]/td[1]").text
- 40 print chuli
- 41 chuli2 = str(chuli.encode("utf-8"))
- 42 m = re.findall(r‘(\w*[0-9]+)\w*‘, chuli2)
- 43 sqltxt = "update cet.cet set leibie=(%s),zongfen=(%s),tingli=(%s),yuedu=(%s),xiezuo=(%s) WHERE zkzh=(%s)" % (
- 44 ss, m[0], m[1], m[2], m[3], i)
- 45 cur.execute(sqltxt)
- 46 conn.commit()
- 47 print str(i) + " finish"
- 48 except Exception, e:
- 49 print e
- 50 driver.close()
- 51 time.sleep(10)
- 52 kaishi(i)
- 53
- 54
- 55 # for j1 in range(1201351511001, 1201351512154):
- 56 for j1 in range(1201351511007, 1201351512154):
- 57 for j2 in range(0, 3):
- 58 for j3 in range(0, 10):
- 59 j = str(j1) + str(j2) + str(j3)
- 60 if str(j2) + str(j3) == "00":
- 61 print "0.0"
- 62 elif str(j2) + str(j3) == "29":
- 63 kaishi(str(j1) + str(j2) + str(j3))
- 64 j4 = str(j1) + "30"
- 65 kaishi(j4)
- 66 else:
- 67 kaishi(j)
- 68 print "END!!!"
- 69 cur.close()
- 70 conn.close()
动态网页爬取