抓站挺好玩的(不过对方心情可就不好说了= =),能够满足某些有趣的需求。Python标准库中的urllib2(在Python3中拆分成urllib.request和urllib.error,这里以Python2作为示例)也很善于做这个事。
对于一般的网站来说,请求并获得网页内容是很简单的,借助于urllib2.urlopen两行代码就能搞定:
>>> import urllib2 >>> res = urllib2.urlopen('http://www.dannysite.com/blog/') >>> data = res.read()
不过两行代码仅能处理理想情况。网络状况或者URL的输入总是多变的,因此在某些情况下,我们可能需要做容错处理。
另外,部分网站可能不大欢迎抓站,或者说做了反盗链处理,那之前的简单法可就不奏效了。这时我们需要将武器伪装一下,比如让它看起来更像浏览器,然后再发起请求:
>>> headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36'} >>> res= urllib2.Request(self.url, headers=self.headers) >>> handle = urllib2.urlopen(req) >>> data = res.read()
这样应该就奏效了!
另外,在Python2中,得到的data会是字符串。如果直接读取该数据的话会得到以下内容:
>>> data[3000:3500] 'blank">\xe6\xba\x90\xe7\xa0\x81</a><a class="nav_btn " href="/about/">\xe5\x85\xb3\xe4\xba\x8e</a></div><div class="clearfloat"></div></div></div><div class="container"><div class="normBox"><div class="fltrt sidebar"><div class="searchBox"><form action="" method="get" id="search_form"><input class="xnorminput" id="search" name="search" type="text" placeholder="\xe6\x90\x9c\xe7\xb4\xa2\xe5\x8d\x9a\xe5\xae\xa2" /></form><div class="searchIcon" onclick="document.getElementById(\'search_form\').submit();"id="search_icon"></div></div><div class="rssBox bg1 mt10 textCenter"'
可以看出,这里的中文数据还是编码之后的,因此要根据其编码进行解码操作:
>>> data[3000:3500].decode('utf8') u'blank">\u6e90\u7801</a><a class="nav_btn " href="/about/">\u5173\u4e8e</a></div><div class="clearfloat"></div></div></div><div class="container"><div class="normBox"><div class="fltrt sidebar"><div class="searchBox"><form action="" method="get" id="search_form"><input class="xnorminput" id="search" name="search" type="text" placeholder="\u641c\u7d22\u535a\u5ba2" /></form><div class="searchIcon" onclick="document.getElementById(\'search_form\').submit();"id="search_icon"></div></div><div class="rssBox bg1 mt10 textCenter"'
因为我知道我的网站是utf-8编码,因此我可以很果断的采用utf8进行解码。不过如果先前不知道呢?一般来说,网页的meta都会声明该页面的编码方式,如:
<meta charset="utf-8">
在Python中,可以这样来取得:
>>> res.info().getparam('charset') 'utf-8'
不过这可不一定准确。还有一个相对准确的方法是利用chardet模块(一个第三方模块):
>>> chardet.detect(data) {'confidence': 0.99, 'encoding': 'utf-8'}
得到编码后就可以顺利进行解码操作了。
今天就先说到这,以后继续分享。
有时需要到别人的网站爬取一些数据,这还是很常见的吧。
抓下来主要干什么