[Python爬虫] Selenium获取百度百科旅游景点的InfoBox消息盒
前面我讲述过如何通过BeautifulSoup获取维基百科的消息盒,同样可以通过Spider获取网站内容,最近学习了Selenium+Phantomjs后,准备利用它们获取百度百科的旅游景点消息盒(InfoBox),这也是毕业设计实体对齐和属性的对齐的语料库前期准备工作。希望文章对你有所帮助~
源代码
1 # coding=utf-8 2 """ 3 Created on 2015-09-04 @author: Eastmount 4 """ 5 6 import time 7 import re 8 import os 9 import sys 10 import codecs 11 from selenium import webdriver 12 from selenium.webdriver.common.keys import Keys 13 import selenium.webdriver.support.ui as ui 14 from selenium.webdriver.common.action_chains import ActionChains 15 16 #Open PhantomJS 17 driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe") 18 #driver = webdriver.Firefox() 19 wait = ui.WebDriverWait(driver,10) 20 global info #全局变量 21 22 #Get the infobox of 5A tourist spots 23 def getInfobox(name): 24 try: 25 #create paths and txt files 26 global info 27 basePathDirectory = "Tourist_spots_5A" 28 if not os.path.exists(basePathDirectory): 29 os.makedirs(basePathDirectory) 30 baiduFile = os.path.join(basePathDirectory,"BaiduSpider.txt") 31 if not os.path.exists(baiduFile): 32 info = codecs.open(baiduFile,'w','utf-8') 33 else: 34 info = codecs.open(baiduFile,'a','utf-8') 35 36 #locate input notice: 1.visit url by unicode 2.write files 37 print name.rstrip('\n') #delete char '\n' 38 driver.get("http://baike.baidu.com/") 39 elem_inp = driver.find_element_by_xpath("//form[@id='searchForm']/input") 40 elem_inp.send_keys(name) 41 elem_inp.send_keys(Keys.RETURN) 42 info.write(name.rstrip('\n')+'\r\n') #codecs不支持'\n'换行 43 #print driver.current_url 44 time.sleep(5) 45 46 #load infobox 47 elem_name = driver.find_elements_by_xpath("//div[@class='basic-info']/dl/dt") 48 elem_value = driver.find_elements_by_xpath("//div[@class='basic-info']/dl/dd") 49 50 #create dictionary key-value 51 #字典是一种散列表结构,数据输入后按特征被散列,不记录原来的数据,顺序建议元组 52 elem_dic = dict(zip(elem_name,elem_value)) 53 for key in elem_dic: 54 print key.text,elem_dic[key].text 55 info.writelines(key.text+" "+elem_dic[key].text+'\r\n') 56 time.sleep(5) 57 58 except Exception,e: #'utf8' codec can't decode byte 59 print "Error: ",e 60 finally: 61 print '\n' 62 info.write('\r\n') 63 64 #Main function 65 def main(): 66 global info 67 #By function get information 68 source = open("Tourist_spots_5A_BD.txt",'r') 69 for name in source: 70 name = unicode(name,"utf-8") 71 if u'故宫' in name: #else add a '?' 72 name = u'北京故宫' 73 getInfobox(name) 74 print 'End Read Files!' 75 source.close() 76 info.close() 77 driver.close() 78 79 main()
运行结果
主要通过从F盘中txt文件中读取国家5A级景区的名字,再调用Phantomjs.exe浏览器依次访问获取InfoBox值。同时如果存在编码问题“'ascii' codec can't encode characters”则可通过下面代码设置编译器utf-8编码,代码如下:
#设置编码utf-8 import sys reload(sys) sys.setdefaultencoding('utf-8') #显示当前默认编码方式 print sys.getdefaultencoding()
其中对应的百度百科InfoBox源代码如下图,代码中基础知识可以参考我前面的博文或我的Python爬虫专利,Selenium不仅仅擅长做自动测试,同样适合做简单的爬虫。
编码问题
此时你仍然可能遇到“'ascii' codec can't encode characters”编码问题。
它是因为你创建txt文件时默认是ascii格式,此时你的文字确实'utf-8'格式,所以需要转换通过如下方法。
1 import codecs 2 3 #用codecs提供的open方法来指定打开的文件的语言编码,它会在读取的时候自动转换为内部unicode 4 if not os.path.exists(baiduFile): 5 info = codecs.open(baiduFile,'w','utf-8') 6 else: 7 info = codecs.open(baiduFile,'a','utf-8') 8 9 #该方法不是io故换行是'\r\n' 10 info.writelines(key.text+":"+elem_dic[key].text+'\r\n')
总结
你可以代码中学习基本的自动化爬虫方法、同时可以学会如何通过for循环显示key-value键值对,对应的就是显示的属性和属性值,通过如下代码实现:
elem_dic = dict(zip(elem_name,elem_value))
但最后的输出结果不是infobox中的顺序,why?
最后希望文章对你有所帮助,还有一篇基础介绍文章,但是发表时总会引发CSDN敏感系统自动锁定,而且不知道哪里引起的触发。推荐你可以阅读~
[python爬虫] Selenium常见元素定位方法和操作的学习介绍
(By:Eastmount 2015-9-6 深夜2点半 http://blog.csdn.net/eastmount/)