python爬虫入门笔记

写在前面

爬虫其实内容的爬取不是最为困难的地方,真正难点在于如何混在群众之中不被发现。由于我在爬虫界还处于幼儿园水平,所以简单写几个脚本爬点美女图片还勉强,想跟亚一爬谈笑风生就不指望了。

urllib基础

html抓取

import urllib2

request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
data = response.read()

data就得到了百度主页的html信息。

html解析

主要就是用re模块来正则匹配

import re

#返回pattern对象
re.compile(string[,flag])  
#以下为匹配所用函数
re.match(pattern, string[, flags])
re.search(pattern, string[, flags])
re.split(pattern, string[, maxsplit])
re.findall(pattern, string[, flags])
re.finditer(pattern, string[, flags])
re.sub(pattern, repl, string[, count])
re.subn(pattern, repl, string[, count])

比较常用的findall,用列表的形式返回全部能匹配的子串。

反爬伪装

现在主流的反爬策略基本基于三个层面:

  • IP层,同一ip访问过多会被封杀
  • HTTP协议层,判断是否真实的浏览器行为
  • 行为层,判断是否真实用户行为
    上述的程序通常在response.read()的时候会报错10054、10060之类的错误。

伪装浏览器Header

用chrome打开浏览器,调试模式,然后打开Network模块,选择其中一个页面,打开Headers页面,其中最后的agent就是请求的身份,不填写身份的话,很容易被反爬策略封杀掉。

user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36'
headers = {'User-Agent' : user_agent}
#    request = urllib2.Request(url, headers)
request = urllib2.Request(url)
request.add_header('User-Agent', user_agent)
response = urllib2.urlopen(request)
page = response.read()

除此之外,有些反爬策略还有反盗链的设计,需要在headers中传入referer

request.add_header('Referer', 'http://www.taobao.com')

proxy代理设置

如果ip访问次数过多也会被封杀,采用代理服务器的方法来定期更换代理。

enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://192.168.0.1:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
    opener = urllib2.build_opener(proxy_handler)
else:
    opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)

超时设置Timeout

在urlopen的时候可以通过设置timeout参数解决网站相应过慢造成的影响。

response = urllib2.urlopen('http://www.baidu.com', timeout=10)

发送数据

用来实现和浏览器之间的行为交互

data = urllib.parse.urlencode({"act": "login", "email": "xxxxx@qq.com", "password": "123456"}).encode('utf-8')
request1 = urllib2.Request(url, data=data)           # POST方法
request2 = urllib2.Request(url+"?%s" % data)         # GET方法
response = urllib2.urlopen(request1)

常用超时异常

try:
    urllib2.urlopen(request)
except urllib2.HTTPError as e:
    print(e.code, e.reason)
except urllib2.URLError as e:
    print(e.errno, e.reason)

服务器cookie检查

import http.cookiejar
cookie_jar = http.cookiejar.CookieJar()
cookie_jar_handler = urllib.request.HTTPCookieProcessor(cookiejar=cookie_jar)
opener = urllib2.build_opener(cookie_jar_handler)        # add_handler
response = opener.open(url)

获取cookie

两种方式,1)直接贴到headers中

request = urllib2.Request(url)
request.add_header('Cookie', "PHPSESSID=btqkg9amjrtoeev8coq0m78396; USERINFO=n6nxTHTY%2BJA39z6CpNB4eKN8f0KsYLjAQTwPe%2BhLHLruEbjaeh4ulhWAS5RysUM%2B; ")

2)构建cookie

import http.cookiejar
cookie = http.cookiejar.Cookie(name="xx", value="xx", domain="xx", ...)
cookie_jar = http.cookiejar.CookieJar()
cookie_jar.set_cookie(cookie)
cookie_jar_handler = urllib.request.HTTPCookieProcessor(cookiejar=cookie_jar)
opener = urllib2.build_opener(cookie_jar_handler)
response = opener.open(url)

HTTP身份认证

password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(realm=None, uri=url, user='username', passwd='password')
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(handler)
response = opener.open(url)

简易图片爬虫

关键的就是解析的时候匹配图片内容,得到了图片链接的话,用wget或者其他模块都能保存图片

patternImg = re.compile('<img.*?src="(.*?)"',re.S)
images = re.findall(patternImg, url_data)

参考资料与推荐文章

http://cuiqingcai.com/
数据时代的反爬虫绝技
一个很“水”的Python爬虫入门代码文件
“史上最详细”的Python模拟登录新浪微博流程
微博话题爬取与存储分析