背景Web Scraping
在大数据时代,一切都要用数据来说话,大数据处理的过程一般需要经过以下的几个步骤 数据的采集和获取 数据的清洗,抽取,变形和装载 数据的分析,探索和预测 数据的展现
其中首先要做的就是获取数据,并提炼出有效地数据,为下一步的分析做好准备。 数据的来源多种多样,以为我本身是足球爱好者,而世界杯就要来了,所以我就想提取欧洲联赛的数据来做一个分析。许多的网站都提供了详细的足球数据,例如:
这些网站都提供了详细的足球数据,然而为了进一步的分析,我们希望数据以格式化的形式存储,那么如何把这些网站提供的网页数据转换成格式化的数据呢?这就要用到Web scraping的技术了。简单地说,Web Scraping就是从网站抽取信息, 通常利用程序来模拟人浏览网页的过程,发送http请求,从http响应中获得结果。
Web Scraping 注意事项
在抓取数据之前,要注意以下几点: 阅读网站有关数据的条款和约束条件,搞清楚数据的拥有权和使用限制 友好而礼貌,使用计算机发送请求的速度飞人类阅读可比,不要发送非常密集的大量请求以免造成服务器压力过大 因为网站经常会调整网页的结构,所以你之前写的Scraping代码,并不总是能够工作,可能需要经常调整 因为从网站抓取的数据可能存在不一致的情况,所以很有可能需要手工调整
Python Web Scraping 相关的库
Python提供了很便利的Web Scraping基础,有很多支持的库。这里列出一小部分
当然也不一定要用Python或者不一定要自己写代码,推荐关注import.io
Web Scraping 代码
下面,我们就一步步地用Python,从腾讯体育来抓取欧洲联赛13/14赛季的数据。
首先要安装Beautifulsoup 1 | pip install beautifulsoup4 |
我们先从球员的数据开始抓取。
球员数据的Web请求是http://soccerdata.sports.qq.com/playerSearch.aspx?lega=epl&pn=2 ,返回的内容如下图所示:
该web服务有两个参数,lega表示是哪一个联赛,pn表示的是分页的页数。
首先我们先做一些初始化的准备工作
1 | from urllib2 import urlopen |
5 | BASE_URL = "http://soccerdata.sports.qq.com" |
6 | PLAYER_LIST_QUERY = "/playerSearch.aspx?lega=%s&pn=%d" |
7 | league = [ 'epl' , 'seri' , 'bund' , 'liga' , 'fran' , 'scot' , 'holl' , 'belg' ] |
9 | player_fields = [ 'league_cn' , 'img' , 'name_cn' , 'name' , 'team' , 'age' , 'position_cn' , 'nation' , 'birth' , 'query' , 'id' , 'teamid' , 'league' ] |
urlopen,urlparse,bs4是我们将要使用的Python库。
BASE_URL,PLAYER_LIST_QUERY,league,page_number_limit和player_fields是我们会用到的一些常量。
下面是抓取球员数据的具体代码:
01 | def get_players(baseurl): |
02 | html = urlopen(baseurl).read() |
03 | soup = bs4.BeautifulSoup(html, "lxml" ) |
04 | players = [ dd for dd in soup.select( '.searchResult tr' ) if dd.contents[ 1 ].name ! = 'th' ] |
06 | for player in players: |
10 | for item in player.contents: |
11 | if type (item) is bs4.element.Tag: |
12 | if not item.string and item.img: |
13 | record.append(item.img[ 'src' ]) |
15 | record.append(item.string and item.string.strip() or 'na' ) |
17 | o = urlparse.urlparse(item.a[ 'href' ]).query |
20 | query = dict ([(k,v[ 0 ]) for k,v in urlparse.parse_qs(o).items()]) |
25 | for i in range ( 0 , 10 - len (record)): |
27 | record.append( unicode (link, 'utf-8' )) |
28 | record.append( unicode (query[ "id" ], 'utf-8' )) |
29 | record.append( unicode (query[ "teamid" ], 'utf-8' )) |
30 | record.append( unicode (query[ "lega" ], 'utf-8' )) |
35 | for url in [ BASE_URL + PLAYER_LIST_QUERY % (l,n) for l in league for n in range (page_number_limit) ]: |
36 | result = result + get_players(url) |
|