python爬取百度搜索动态网页

我最近学习用python编写一个简单的网络爬虫,刚开始学习scrapy来爬取,觉得费时间学习完scrapy还不如自己用urllib2和lxml直接写一个简单的爬虫,于是下载了firefox和firebug来研究。

Firebug是scrapy官网推荐的xpath分析插件。首先说说,xpath是xml路径语言,xpath可以用于解析xml、html等格式文件中的元素文件路径。我们通过firebug的选择元素按钮(红色框)点击网页中的链接,然后firebug自动跳转到响应的元素代码处,右键弹出菜单点击复制xpath路径,复制下来的xpath路径是:/html/body/div[2]/div[3]/div[1]/div[3]/div[1]/h3/a。这是该链接的精确xpath路径,在lxml的xpath功能函数中输入这个路径,可以获取该链接元素。该元素属性href对应的就是相应的链接。然而我试图查找百度搜索网页中所有类似的链接,我需要一个模糊查找路径。

能爬取动态页面的技术java_能爬取动态页面的技术java

Firefox中还有两个更加强大的插件:firepath和xpath checker。我安装这两个插件。其中firepath插件附属到firebug上,xpath checker添加到网页界面右键菜单上的viewxpath菜单。

我切换到firebug的firepath标签页,同样通过选择元素按钮选择链接,获取的xpath为.//*[@id='1']/h3/a,显然比firebug直接获取的xpath简单多了。其中.表示从当前路径开始查找,这里自然就是从最上级开始查找;//表示获取当前路径下后续代码指定的所有元素;*表示任意代码,但是必须包含[]内代码指定的属性;@id=’1’表示包含一个属性,名为id,值为1。右键点击网页,选择view xpath,

 

能爬取动态页面的技术java_python_02

输入.//*[@id='1']/h3/a,发现符合该模糊路径的xpath元素只有一个,这说明firepath查找的xpath更加简单。我们去掉xpath路径中的id属性,发现所有百度搜索的链接都搜索到了。

接下来我们通过urllib2获取搜索页面,然后用xpath提取元素,获取href属性对应的链接。然而我发现这个链接并不是真实的链接,是百度提供的动态链接,每次搜索都会变。于是我提取该链接继续用urllib2访问,结果返回百度的search error页面,说明百度用动态页面屏蔽了爬虫。

爬虫一般能爬取静态网页,动态网页比较麻烦。爬取动态网页最简单的方法是开启浏览器模拟人的行为去点击动态链接,然后再获取真实链接。这里就用到selenium这个web自动化测试工具来模拟人的行为。下载安装selenium的python库,输入以下代码:

from selenium import webdriver
from selenium.webdriver.common.keys importKeys
import lxml.etree as etree
import lxml.html.soupparser as soupparser
 
browser = webdriver.Firefox()
browser.get("http://www.baidu.com")
browser.implicitly_wait(0.5)
browser.find_element_by_id("kw").send_keys(u"武汉")
browser.find_element_by_id("su").click()
eleList=browser.find_elements_by_xpath(".//*/h3/a")
curHandle=browser.current_window_handle
#searchList=dict()
itemNum=len(eleList)
#网页上边有固定菜单
solidForm=browser.find_element_by_xpath(".//*[@id='head']/div[1]/div[1]")
solidH=solidForm.size['height']
for i in xrange(itemNum):
    #执行js代码自动滚动页面直到链接可见,否则报错
    js="scroll(0,%s)"%(eleList[i].rect['y']-solidH)
   browser.execute_script(js)
   try:
       browser.implicitly_wait(30)
       eleList[i].click()
   except:
       print "timeout"
       browser.close()
                     #selenium目前只能在新窗口打开网页,不能在新标签页中打开网页
       browser.switch_to_window(curHandle)
       continue
all_handles=browser.window_handles
#找到新开的窗口
   browser.switch_to_window(all_handles[-1])
   searchList[browser.title]=browser.current_url
   print browser.title,":",browser.current_url
    browser.close()
   browser.switch_to_window(curHandle)
browser.back()
browser.quit()

 

能爬取动态页面的技术java_爬虫_03