python网络爬虫抓取ajax动态网页数据:以抓取KFC门店地址为例

时间:2021-12-28 08:53:08


一,尝试用BeautifulSoup抓取

先打开KFC网站门店列表页面:http://www.kfc.com.cn/kfccda/storelist/index.aspx

可以看到门店列表如下图:

python网络爬虫抓取ajax动态网页数据:以抓取KFC门店地址为例


打开Chrome Developer Tools观察页面结构,找到标签如下:

python网络爬虫抓取ajax动态网页数据:以抓取KFC门店地址为例

发现要的数据位于id='listhtml'的表里,门店地址数据位于第二个tr开始的行里,尝试用bs抓取:

url = 'http://www.kfc.com.cn/kfccda/storelist/index.aspx'
html = urllib.urlopen(url).read().decode('utf-8')
bsObj = BeautifulSoup(html, "html.parser")
print bsObj.find('tbody', {'id':'listhtml'})

输出:

<tbody id="listhtml">
</tbody>


数据由ajax动态生成,抓取失败。


二,用selenium + PhantomJS抓取

url = 'http://www.kfc.com.cn/kfccda/storelist/index.aspx'
# html = urllib.urlopen(url).read().decode('utf-8')
# bsObj = BeautifulSoup(html, "html.parser")
# print bsObj.find('tbody', {'id':'listhtml'})
driver = webdriver.PhantomJS(executable_path='/home/guowei/bin/phantomjs/bin/phantomjs')
driver.get(url)
print driver.find_element_by_id('listhtml')

输出结果:

<selenium.webdriver.remote.webelement.WebElement object at 0xb6823a8c>


有抓取到对象,但不能确定是否是包含需要的数据,再分析网页结构,抓出第一家门店地址看看:

print driver.find_element_by_id('listhtml').find_element_by_xpath('//tr[2]/td[1]').text
输出结果:
茂名餐厅

说明已经成功抓取动态网页的数据!

三、抓取KFC门店数据

观察门店数据表格,所需数据从第二行开始,每行前2列表格数据有用,因此抓取代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium import webdriver
import time

url = 'http://www.kfc.com.cn/kfccda/storelist/index.aspx'
driver = webdriver.PhantomJS(executable_path='/home/guowei/bin/phantomjs/bin/phantomjs')
driver.get(url)

time.sleep(2)

for i in range(1,11):
shopName_xpath = '//tr[' + str(i + 1) + ']/td[1]'
shopAddress_xpath = '//tr[' + str(i + 1) + ']/td[2]'
shopName = driver.find_element_by_css_selector('#listhtml').find_element_by_xpath(shopName_xpath).text
shopAddress = driver.find_element_by_css_selector('#listhtml').find_element_by_xpath(shopAddress_xpath).text
print shopName
print shopAddress
输出结果:

茂名餐厅
吴江路269号2层
翔川餐厅
妙镜路1118号E号商铺
动力南广场餐厅
石龙路750-3号上海南站地下商场南馆
江苏餐厅
江苏路398号1、2层
威宁餐厅
天山路352号101和201
思贤餐厅
思贤路778--180号
惠乐餐厅
人民西路955号
柳州餐厅
沪闵路9001号上海南站站厅层
真北餐厅
桃浦路328号
马陆弘基餐厅
马陆镇沪宜公路2398/2400号

四、总结

time.sleep()非常重要,如果网速太慢有时候ajax程序还未从服务器取得数据,当然用检测一个特定HTML标签的方式会更高效,比如检测上述数据所在表格最后一行最后一格已经载入就可以开始抓取数据。