爬虫

基本流程

  1. 准备工作 #分析页面等
  2. 获取数据
  3. 解析内容
  4. 保存数据

设计思路

  1. 确定需要爬取的页面url地址
  2. 通过http请求获取http页面
  3. 提取html页面有用数据:

    a.如果是需要的内容,保存起来

    b.如果是url地址,执行第2步继续提取

可以做爬虫的语言很多,如PHP、java、c/c++、python等

  • php天生不是干这个的。而且对多线程、异步支持不够好。并发处理能力若,爬虫是工具性程序,对效率要求高。
  • java的网络爬虫生态圈也很完善,是python最大对手。但java本身很笨重,代码量很大。重构成本高,任何修改会导致代码大量变动。爬虫经常需要修改部分内容。
  • C/C++运行效率几乎最强,但是学习成本很高,代码成型比较慢。能用C/C++做爬虫不是正确的选择。
  • python语法优美代码简洁、开发效率高,支持模块多,次昂管http请求模块很多,还有强大的爬虫Scrapy,以及成熟高效的分布式策略,其他接口也很方便(胶水语言)

通用爬虫 聚焦爬虫

通用爬虫

搜索引擎用的爬虫系统。

目标:尽可能把互联网所有网页下载下来形成备份,再对这些网页做相关处理,最后提供给用户一个搜索接口

搜索引擎如何获取新网站的url地址:

  1. 主动向搜索引擎提交网址。
  2. 在其他网站里设置外链(友情链接、外部链接)
  3. 搜索引擎会和DNS服务商合作,快速收录新的网站。

通用爬虫并不是万物皆可爬,它也需要遵守协议。(robots协议 规定哪些可以爬,哪些不让爬// 并不是所有爬虫都遵守,一般只有大型搜索引擎遵守,我们自己写的爬虫,就不管了)

通用爬虫工作流程

爬取网页---存储数据-----内容处理-----提供检索/排名服务

通用爬虫缺点:

  1. 只能提供和文本相关的内容(html、word等),不能提供多媒体内容(音乐、图片等)
  2. 提供的内容千篇一律,不能针对不同人有不同结果,
  3. 不能理解人类语义上的检索。

聚焦爬虫

为了解决通用爬虫存在的问题

针对某种内容的爬虫

面向主题爬虫、会针对某种特定内容爬取信息。

http和https工作原理

请求与响应。

请求主要分为get和post两种(区别:信息是否隐藏)


urllib2库的基本使用

第一个爬虫程序


import urllib2  
​  
ua_headers = {  
 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"  
}  
​  
# 通过urllib2.Request() 方法构造一个请求对象  
request = urllib2.Request("http://www.baidu.com/", headers = ua_headers)  
​  
# 向指定的url地址发送请求,并返回服务器响应的类文件对象  
response = urllib2.urlopen(request)  
​  
# 服务器返回的类文件对象支持Python文件对象的操作方法  
# read()方法就是读取文件里的全部内容,返回字符串  
html = response.read()  
​  
# 返回 HTTP的响应码,成功返回200,4服务器页面出错,5开头的,服务器问题  
print response.getcode()  
​  
# 返回 返回实际数据的实际URL,防止重定向问题  
print response.geturl()  
​  
# 返回 服务器响应的HTTP报头  
print response.info()

注:

  • user-agent 必须设置的内容(模拟浏览器),反爬斗争第一步。

第二个爬虫程序(user-agent列表 反爬)


import urllib2  
import random  
​  
url = "http://www.baidu.com/"  
​  
# 可以是User-Agent列表,也可以是代理列表  
ua_list = [  
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1",  
 "Mozilla/5.0 (Windows NT 6.1; rv2.0.1) Gecko/20100101 Firefox/4.0.1",  
 "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",  
 "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",  
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_7\_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"  
]  
​  
# 在User-Agent列表里随机选择一个User-Agent  
user_agent = random.choice(ua_list)  
​  
# 构造一个请求  
request = urllib2.Request(url)  
​  
# add_header()方法 添加/修改 一个HTTP报头  
#也可以用第一种方法  
request.add_header("User-Agent", user_agent)  
​  
# get_header() 获取一个已有的HTTP报头的值,注意只能是第一个字母大写,其他的必须小写  
print request.get_header("User-agent")  

get和post的区别

  • get:url附带带参数
  • post:url不带参数
  • get请求参数在queryString中保存
  • post请求单数在porm表单中保存

第三个爬虫程序:(模拟post请求的爬虫)

import urllib  
import urllib2  
​  
# 通过抓包的方式获取的url,并不是浏览器上显示的url  
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"  
​  
# 完整的headers  
#注意要在原本数据上去掉没有的和不能留的信息  
headers = {  
 "Accept" : "application/json, text/javascript, */*; q=0.01",  
 "X-Requested-With" : "XMLHttpRequest",  
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",  
 "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",  
 }  
​  
# 用户接口输入  
key = raw_input("请输入需要翻译的文字:")  
​  
# 发送到web服务器的表单数据(通过抓包获得)  
formdata = {  
"type" : "AUTO",  
"i" : key,  
"doctype" : "json",  
"xmlVersion" : "1.8",  
"keyfrom" : "fanyi.web",  
"ue" : "UTF-8",  
"action" : "FY_BY_CLICKBUTTON",  
"typoResult" : "true"  
}  
​  
# 经过urlencode转码(有中文的时候需转)  
data = urllib.urlencode(formdata)  
​  
# 如果Request()方法里的data参数有值,那么这个请求就是POST  
# 如果没有,就是Get  
#因为get没有请求体,post有请求体  
request = urllib2.Request(url, data = data, headers = headers)  
​  
print urllib2.urlopen(request).read()  

异步 ajax加载方式的数据的获取

ajax方式加载的页面,数据格式一定是JSON

拿到json,就是拿到了要获取的数据



import urllib  
import urllib2  
​  
url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"  
​  
#请求头  
headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}  
​  
#post要传递的表单原始数据  
formdata = {  
 "start":"0",  
 "limit":"20"  
 }  
​  
#转码为可识别的post传递的数据  
data = urllib.urlencode(formdata)  
​  
request = urllib2.Request(url, data = data, headers = headers)  
​  
print urllib2.urlopen(request).read()  
​  
##直接请求得到json就是我们要的数据  

利用cookie模拟登录

import urllib2  

url = "http://www.renren.com/410043129/profile"  
​  
headers = {  
 "Host" : "www.renren.com",  
 "Connection" : "keep-alive",  
 #"Upgrade-Insecure-Requests" : "1",  
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",  
 "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",  
 "Referer" : "http://www.renren.com/SysHome.do",  
 ########################################  
 #这个东西是千万不能要!!!  
 #"Accept-Encoding" : "gzip, deflate, sdch",  
 "Cookie" : "anonymid=ixrna3fysufnwv; _r01_=1; depovince=GW; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484400895379; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484400890914; JSESSIONID=abcX8s_OqSGsYeRg5vHMv; jebecookies=0c5f9b0d-03d8-4e6a-b7a9-3845d04a9870|||||; ick_login=8a429d6c-78b4-4e79-8fd5-33323cd9e2bc; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; p=0cedb18d0982741d12ffc9a0d93670e09; ap=327550029; first_login_flag=1; ln_uact=mr_mao_hacker@163.com; ln_hurl=http://hdn.xnimg.cn/photos/hdn521/20140529/1055/h_main_9A3Z_e0c300019f6a195a.jpg; t=56c0c522b5b068fdee708aeb1056ee819; societyguester=56c0c522b5b068fdee708aeb1056ee819; id=327550029; xnsid=5ea75bd6; loginfrom=syshome",  
 "Accept-Language" : "zh-CN,zh;q=0.8,en;q=0.6",  
}  
​  
request = urllib2.Request(url, headers = headers)  
​  
response = urllib2.urlopen(request)  
​  
print response.read()  

访问https协议的页面


import urllib2  
​  
###########添加的内容##########################  
import ssl  
# 忽略SSL安全认证  
context = ssl._create_unverified_context()  

url = "https://www.12306.cn/mormhweb/"  
#url = "https://www.baidu.com/"  
​  
headers = {  
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"  
 }  
request = urllib2.Request(url, headers = headers)  
​  
# 添加到context参数里  
response = urllib2.urlopen(request, context = context)  
​  
print response.read()·


贺崇德
4 声望1 粉丝