上面链接爬虫只是能将我们所需的网页下载下来,但是,我们没办法得到我们想要的数据。因此,我们只有URL管理器和URL下载器是不足以组成一个完整的网络爬虫的。我们还需要URL解析器,对数据进行提取。
数据抓取(Scraping)有三种方式:1.正则表达式;2.第三方包——BeautifulSoup;3.lxml模块
1.正则表达式(regex)方法。
''' 数据抓取:从网页中抓取一些感兴趣的数据,然后实现某些事情。主要有三种方法——正则;BeautifulSoup模块和lxml模块。 ''' # 正则表达式 # 帮助文档https://docs.python.org/2/howto/regex.html import urllib2 import re def download(url, user_agent= "wswp", num_retries= 2): print "Download :", url headers= {"User_agent": user_agent} request= urllib2.Request(url, headers=headers) try: html= urllib2.urlopen(request).read() except urllib2.URLError as e: print "Download Error :", e.reason html= None if num_retries> 0: if hasattr(e,"code") and 500<= e.code< 600: return download(url, user_agent, num_retries-1) return html if __name__ == "__main__": url = "http://example.webscraping.com/view/United-Kingdom-239" html = download(url) kingdom = re.findall('<td class="w2p_fw">(.*?)</td>',html) # print kingdom # 只提取面积属性 kingdom_square_1 = re.findall('<td class="w2p_fw">(.*?)</td>', html)[1] print kingdom_square_1 # 上面例子只能抓取固定不变的网页中的面积,但是,如果网页发生改变,第二行不再是面积时,就不能抓取到了。所以,下面做一些改进。 ''' <tr id="places_area__row"><td class="w2p_fl"><label for="places_area" id="places_area__label">Area: </label></td><td class="w2p_fw">244,820 square kilometres</td><td class="w2p_fc"></td></tr> ''' # 将其父元素<tr>加入进来,由于该元素有ID属性,所以,应该是唯一的。 kingdom_square_2 = re.findall('<tr id="places_area__row"><td class="w2p_fl"><label for="places_area" id="places_area__label">Area: </label></td><td class="w2p_fw">(.*?)</td><td class="w2p_fc"></td></tr>', html) print kingdom_square_2 # 上一个版本虽然比上一个的要精准一些,但是也会遇到一些问题,比如:双引号变为单引号,<td>标签之间添加多余的空格,或者变更area_label等 kingdom_square_3 = re.findall('<tr id="places_area__row">.*?<td\s*class=["\']w2p_fw["\']>(.*?)</td>', html) print kingdom_square_3 # 总结:正则表达式比较便捷,但是这种方式太过脆弱,只能抓取静态的网页,容易在网页更新后出现问题。