写在前面
爬虫其实内容的爬取不是最为困难的地方,真正难点在于如何混在群众之中不被发现。由于我在爬虫界还处于幼儿园水平,所以简单写几个脚本爬点美女图片还勉强,想跟亚一爬谈笑风生就不指望了。
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模拟登录新浪微博流程
微博话题爬取与存储分析