python动态⽹页爬取——四六级成绩批量爬取
需求:
四六级成绩查询⽹站我所知道的有两个:学信⽹(www.chsi/cet/)和99宿舍(cet.99sushe/),这两个⽹站采⽤的都是动态⽹页。我使⽤的是学信⽹,好了,⽹
站截图如下:
⽹站的代码如下:
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,即:www.chsi/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=color
Red>403 </SPAN><BR><SPAN class=color666>听⼒:</SPAN> 132 <BR><SPAN class=color666>阅读:</SPA 该代码显⽰了成绩,可以知道,该⽹站使⽤的是动态⽹页,⽤的JavaScript或者Ajax.js还是其他的我就不知道了0.0。上⾯为需求。
前⾔:使⽤过BeautifulSoup爬取过,但是BeautifulSoup是爬取不了动态⽹页的,上各种论坛各种资料,⽤了n种东西,scapy,pyqt等等,⾛了真⼼不少弯路,不是不⾏,应该是我不会
⽤,最终⽤了selenium和phantomjs,这两个应该也是⽬前最流⾏的爬⾍模块了吧。
⼀、导⼊selenium和phantomjs
1from selenium import webdriver
2
3 driver = webdriver.PhantomJS(executable_path='D:\phantomjs-2.1.')
(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分别是准考证号,姓名和提交
⼆、字符处理
提交之后就可以直接查了:
1print driver.find_element_by_xpath("//tr[3]/td[1]").text
2print driver.find_element_by_xpath("//tr[6]/td[1]").text
代码说明:
1.查看姓名
2.查看分数及其具体成绩
打印之后为:
姓名
403
听⼒
132
阅读
147
写作
142
之后要对分数进⾏字符串处理,选取各部分的数字,这⾥我们采⽤re模块:
1import re
2 m = re.findall(r'(\w*[0-9]+)\w*', chuli2)
其中m是数组,输出的是["403","132","147","142"]
三、数据库
我们学校也不知说很渣还是⼈性化,反正公布了全校的四六级准考证号,当然,是excel的,需要导⼊mysql数据库,打开Excel之后,我发现微软⼤法和Oracle真是⽜逼啊,Excel365居然有mysql workbench连接部分
数据库代码如下:
1import 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()
ute("select name where zkzh=(%s)" % i)
7 xm = cur.fetchone()[0]
8print"Name is " + xm
9 sqltxt = " 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)
ute(sqltxt)
12 connmit()
13 cur.close()
14 conn.close()
代码说明:
3.python连接数据库代码
6.连接数据库取得姓名部分
9.这⾏我好⽆语啊,使⽤‘“+ss+”’这样的写法⼀直报错,最终了半天资料,这个写法我不太喜欢,但是凑合着⽤吧。
12.记得⼀定要提交事务!!!commit()!!!不然是没有效果的
四、使⽤代理服务器(保留以后写)
运⾏了⼀段时间之后,⼤概抓了⼏百⼈的吧,然后就出现要求验证码了,解决办法只能处理验证码或者使⽤代理服务器了,这部分继续加强学习再弄出来了↖(^ω^)↗
五、源代码和效果
1# encoding=utf8
2
3import MySQLdb
4import re
5import time
6
7from selenium import webdriver
8
网页colspan9# 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 = 'www.chsi/cet/query'
14
15
16def kaishi(i):
17print i,
18print" start"
19try:
20 ute("select name where zkzh=(%s)" % i)
21 xm = cur.fetchone()[0]
22print"Name is " + xm
23 driver = webdriver.PhantomJS(executable_path='D:\phantomjs-2.1.')
24 (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 = de("utf-8"))
31 ss = ""
32if leibie2.decode("utf-8") == '英语四级'.decode("utf-8"):
33 ss = 4
34else:
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
40print chuli
41 chuli2 = de("utf-8"))
42 m = re.findall(r'(\w*[0-9]+)\w*', chuli2)
43 sqltxt = " 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 ute(sqltxt)
46 connmit()
47print str(i) + " finish"
48except Exception, e:
49print e
50 driver.close()
51 time.sleep(10)
52 kaishi(i)
53
54
55# for j1 in range(1201351511001, 1201351512154):
56for j1 in range(1201351511007, 1201351512154):
57for j2 in range(0, 3):
58for j3 in range(0, 10):
59 j = str(j1) + str(j2) + str(j3)
60if str(j2) + str(j3) == "00":
61print"0.0"
62elif str(j2) + str(j3) == "29":
63 kaishi(str(j1) + str(j2) + str(j3))
64 j4 = str(j1) + "30"
65 kaishi(j4)
66else:
67 kaishi(j)
68print"END!!!"
69 cur.close()
70 conn.close()
参考资料:
1.my.oschina/u/2420420/blog/489205?fromerr=MX68uajh
2.wwwblogs/hearzeus/p/5157016.html
总结:python的字符串处理细节真的很重要,动不动就输出错误,还有IDE的编码不⼀样,记得还有个系统编码,字符编码,环境编码,数据库编码等等都要⼀致!!!
ps后记:1.这⼏天别⼈各种同学聚会,然⽽,⾃⼰也总是那么“幸运”,中学所碰到的班级对外特活跃特团结的样⼦,但是初中⾼中毕业那么久了,聚会是⼏乎没有过。。。。昨晚梦见了那些⼈那些事,也不知道他们怎么样了。昨天有⼀篇新闻报道了⼀⼤学⼀宿舍毕业20年,年年聚会的那样⼦真好。
2.对于爱情的烦恼,莫过于明明很喜欢却发现⾃⼰和她完全不是⼀个“世界”的⼈,然后也很少她说话,再然后就是⽤“嗯”“哦”来回复她的主动聊天,再然后联系越来越少,再然后连门都不敢出了,怕这个世界,有时虽然也会⾃嘲“活该孤独终⽼”,但是有啥办法呢?过年了,回到家,过着越来越淡的年,看着⼀同长⼤的⼈,吃着⼏⼗年⼀样的菜和饭,难不得矫情⼀下。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论