使用python爬取MedSci上的期刊信息
使用python爬取medsci上的期刊信息,通过设定条件,然后获取相应的期刊的的影响因子排名,期刊名称,英文全称和影响因子。主要过程如下:
首先,通过分析网站http://www.medsci.cn/sci的交互过程。可以使用谷歌或火狐浏览器的“审查元素-->Network”,然后就可以看到操作页面就可以看到网站的交互信息。当在网页上点击“我要查询”时,网页会发送一个POST消息给服务器,然后,服务器返回查询结果
然后,将查询到的结果使用正则表达式提取出需要的数据。
最后将提取出的数据输出到文件。
代码的关键在于分析POST数据报,找出需要发送到服务器的数据,以及HTTP的报文头的填写。
通过浏览器的“审查元素-->Network-->POST的链接-->Headers”,能够找到一个form Data的数据表格,这个数据表格保存着所有的查询条件。
在代码中通过对这些数据表格进行赋值,即可模拟浏览器发送post请求,然后将得到html代码。接下来只需对获取到的数据做进一步的处理即可。
代码中的部分变量做简单的说明:
num:表示要获取的期刊的数目
value中的参数保存着查询条件:每个子条件的参数名意义如下:
fullname:期刊关键字
province:期刊领域中的大类
city:期刊中的二级分类、
impact_factor_b:IF范围小于的值
impact_factor_s:IF范围大于的值
rank:排列方式
这个代码有个bug,当某个期刊的影响因子为空或未知时,则这个期刊必须要在最末的位置,否则代码就可能产生异常,并且在最后的结果不会输出影响因子未知的期刊。
代码如下:
1 #!/usr/bin/python 2 #coding=utf-8 3 import urllib 4 import urllib2 5 import re 6 import time 7 8 global rank 9 global num 10 url = 'http://www.medsci.cn/sci/index.do?action=search' 11 headers = { 12 'POST':url, 13 'Host':'www.medsci.cn', 14 'Origin':'http://www.medsci.cn', 15 "Referer":"http://www.medsci.cn/sci", 16 "User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36", 17 } 18 value = { 19 "fullname": "", 20 "province": "医学", 21 "city": '', 22 "impact_factor_b": "0", 23 "impact_factor_s": "0", 24 "rank": "if_rank_b", 25 "Submit": "我要查询" 26 } 27 28 def getData(impact): 29 value["impact_factor_b"] = impact 30 data = urllib.urlencode(value); 31 req = urllib2.Request(url, data) 32 for key in headers: 33 req.add_header(key, headers[key]) 34 response = urllib2.urlopen(req) 35 html = response.read(); 36 return html 37 38 def saveData(html, rank): 39 r1 = re.findall(r'_blank >([A-Z|\-|a-z|\s|\(|\)|&]*?)</a>', html); 40 r2 = re.findall(r'<br>([A-Z|a-z|\-|\s|&|\(|\)]+?)</td>', html); 41 r3 = re.findall(r'\n([0-9|.]+?)[\s|<]', html); 42 43 le1 = len(r1) 44 le2 = len(r2) 45 le3 = len(r3) 46 le = le1 47 if le2 < le: 48 le = le2; 49 if le3 < le: 50 le = le3 51 52 count = 0 53 flag = True 54 if le < 50: 55 flag = False 56 while count < le and rank < num: 57 rank += 1 58 #print 'count:',count,', le:',le,', rank:',rank,",num:",num 59 str1 = str(rank)+","+r1[count]+","+r2[count]+","+r3[count]+"\n" 60 count += 1 61 f.write(str1) 62 63 return r3[count-1], rank,flag #return the last impact 64 65 if __name__ == "__main__": 66 f = open("res.csv","w+") 67 impact = 0 68 rank = 0 69 num = 100 70 flag = True 71 while rank < num and flag: 72 html = getData(impact); 73 impact, rank, flag = saveData(html, rank); 74 print 'already get data number:',rank 75 time.sleep(2); 76 f.close() 77 print 'finished!'