1.网络爬虫
- 定义:网络蜘蛛,网络机器人,抓取网络数据的程序
- 总结:用python程序去模仿人去访问网站,模仿的越逼真越好
- 爬去数据的目的:通过有效的大量数据分析市场走势,公司决策
2.企业获取数据的方式
- 公司自有数据
- 第三方数据平台购买
数据堂,贵阳大数据交易所 - 爬虫抓取数据
市场上没有或者价格太高,利用爬虫程序爬取
3.Python 做爬虫优势
请求模块,解析模块丰富成熟,强大的scrapy框架
PHP:对多线程,异步支持不太好
JAVA:代码笨重,代码量很大
C / C++:虽然效率高,但是代码成型很慢
4.爬虫分类
- 通用网络爬虫(搜索引擎引用,需要遵守robots协议)
https://www.taobao.com/robots.txt- 搜索引擎如何获取一个新网站的URL
- 网站主动向搜索引擎提供(百度站长平台)
- 和DNS服务网(万网),快速收录新网站
- 搜索引擎如何获取一个新网站的URL
- 聚焦网络爬虫
自己写的爬虫程序:面向主题的爬虫,面向需求的爬虫
5.爬取数据步骤
- 确定需要爬取的URL地址
- 通过HTTP/HTTPS 协议来获取相应的HTML页面
- 提取HTML页面有用的数据
- 所需数据,保存
- 页面中有其他的URL,继续 第2步
6.Anaconda和Syder
- Anaconda :开源的Python发行版本
- Spyder:集成开发环境
Spyder常用快捷键- 注释/取消注释 :CTRL+1
- 保存:CTRL+s
- 运行程序:F5
- 自动补全:TAB
7.Chrome浏览器插件
- 安装步骤
- 右上角 - 更多工具 - 扩展程序
- 点开右上角 - 开发者模式
- 把插件 拖拽到 浏览器页面,释放鼠标,点击 添加扩展...
- 插件介绍
- Proxy SwitchDmega:代理切换插件
- Xpath Helper:网页数据解析插件
- JSON View:查看json格式的数据(好看)
8.Fiddler抓包工具
- 抓包工具设置
- Tools - options - HTTPS - from browers only
- connections:设置端口号 8888
- 设置浏览器代理
Proxy SwitchOmega - 设置 - 新建情景模式 - HTTP 127.0.0.1 8888 - 应用选项
浏览器右上角图标 - AID1806 - 访问百度
9.WEB
- HTTP 和 HTTPS
- HTTP:80
- HTTPS:443,HTTP的升级版,加了一个安全套接层
- GET 和 POST
- GET:查询参数都会在URL上显示出来
- POST:查询参数和需要提交的数据隐藏在FORM表单里的,不会再URL地址上显示
- URL:统一资源定位符
https:// item.jd.com :80 /11993134.html #detail
协议 域名/ip地址 端口 访问资源的路径 锚点 - User-Agent
记录用户的浏览器,操作系统等,为了让用户获取更好的HTML页面效果User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Mozilla Firefox:(Gecko内核)
IE:Trident(自己的内核)
Linux:KTHML(like Gecko)
Apple:Webkit(like KHTML)
Google:Chrome(like Webkit)
其它浏览器都是模仿IE/Chrome
10.爬虫请求模块
- 版本
- python2:urllib2,urllib
- python3:把urllib和urllib2合并,urllib.request
- 常用方法
- urllib.request.urlopen('网址')
- 作用:向网站发起一个请求并获取响应
字节流 = response.read()
字符串 = response.read().decode('utf-8')
encode() 字符串 --> bytes数据类型
decode() bytes数据类型 -->字符串import urllib.request # response为响应对象 response = urllib.request.urlopen("http://www.baidu.com/") html = response.read().decode("utf-8") print(html) #encode() 字符串 --> bytes数据类型 #decode() bytes数据类型 --> 字符串
- 重构User-Agent
- 不支持重够User-Agent:urlopen()
- 支持重构User-Agent
urllib.request.Request(添加User-Agent)
- 作用:向网站发起一个请求并获取响应
- urllib.request.Request('网址',headers='字典')
User-Agent是爬虫和反爬虫斗争的第一步,发送请求必须带User-Agent- 使用流程
- 利用Request方法构建请求对象
- 利用urlopen()方法获取响应对象
- 利用响应对象的read().decode('utf-8')获取内容
- 响应对象response的方法
- read():读取服务器响应的内容
- getcode()
- 作用
返回HTTP的响应码
print(response.getcode())
200:成功
4xx:服务器页面出错
5xx:服务器出错
- 作用
- geturl()
- 作用:返回实际数据的URL(防止重定向问题)
import urllib.request url = "http://www.baidu.com/" headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"} # 1.创建请求对象(有User-Agent) req = urllib.request.Request(url,headers=headers) # 2.获取响应对象(urlopen()) res = urllib.request.urlopen(req) # 3.响应对象read().decode("utf-8") #html = res.read().decode("utf-8") #print(html) print(res.getcode()) print(res.geturl())
- 作用:返回实际数据的URL(防止重定向问题)
- 使用流程
- urllib.request.urlopen('网址')
- urllib.parse模块
- urlencode(字典) ##注意:参数一定要为字典
urlencode({'wd':'美女'})
wd=%e8... ...
tedu = {'wd':'达内科技'}
练习:
请输入你要搜索的内容:美女
保存到本地文件:美女.htmlimport urllib.request import urllib.parse #拼接URL baseurl = "http://www.baidu.com/s?" key = input("请输入要搜索的内容:") #进行urlencode()编码 wd = {"wd":key} key = urllib.parse.urlencode(wd) url = baseurl + key headers = {"User-Agent":"Mozilla/5.0"} # 创建请求对象 req = urllib.request.Request(url,headers=headers) # 获取响应对象 res = urllib.request.urlopen(req) html = res.read().decode("utf-8") #写入本地文件 with open("搜索.html","w",encoding="gb18030") as f: f.write(html)
- quote(字符串)
key = urllib.parse.quote('字符串')
key = urllib.parse.quote('字符串')
baseurl = 'http://www.baidu.com/s?wd='
key = input('请输入内容:')
#进行quote()编码key = urllib.parse.quote(key)
url = baseurl + key
print(url)
示例:import urllib.request import urllib.parse #拼接URL baseurl = "http://www.baidu.com/s?wd=" key = input("请输入要搜索的内容:") #进行quote()编码 key = urllib.parse.quote(key) url = baseurl + key print(url) headers = {"User-Agent":"Mozilla/5.0"} # 创建请求对象 req = urllib.request.Request(url,headers=headers) # 获取响应对象 res = urllib.request.urlopen(req) html = res.read().decode("utf-8") #写入本地文件 with open("搜索2.html","w",encoding="gb18030") as f: f.write(html)
- urlencode(字典) ##注意:参数一定要为字典
-
练习
百度贴吧数据抓起
要求:-
输入要抓取的贴吧名称
-
输入爬取的起始页面和终止页
-
把每一页的内容保存到本地
第一页.html 第二页.html ... ...
步骤:-
找URL规律,拼接URL
第一页:http://tieba.baidu.com/f?kw=??&pn=0
第二页:http://tieba.baidu.com/f?kw=??&pn=50
第三页:http://tieba.baidu.com/f?kw=??&pn=100
...
第n页:pn = (n-1)*50 -
获取网页内容(发请求或响应)
-
保存(本地文件,数据库)
解析:import urllib.request import urllib.parse import random import time # 随机获取1个User-Agent header_list = [{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}, {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"}, {"User-Agent":"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.0)"}] headers = random.choice(header_list) # 主体程序 name = input("请输入贴吧名:") begin = int(input("请输入起始页:")) end = int(input("请输入终止页:")) # 对贴吧名name进行编码 kw = {"kw":name} kw = urllib.parse.urlencode(kw) # 拼接URL,发请求,获响应 for i in range(begin,end+1): # 拼接URL pn = (i-1)*50 baseurl = "http://tieba.baidu.com/f?" url = baseurl + kw + "&pn=" + str(pn) # 发起请求 req = urllib.request.Request(url,headers=headers) res = urllib.request.urlopen(req,timeout=5) time.sleep(2) html = res.read().decode("utf-8") # 写入文件 filename = "第" + str(i) + "页.html" with open(filename,"w",encoding="utf-8") as f: print("正在爬取第%d页" % i) f.write(html) print("第%d页爬取成功" % i) print("*" * 30)
函数写:
import urllib.request # 读取页面 def readPage(url): headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"} req = urllib.request.Request(url,headers=headers) res = urllib.request.urlopen(req) html = res.read().decode("utf-8") return html # 写入文件 def writePage(filename,html): with open(filename,"w",encoding="gb18030") as f: f.write(html) print("写入成功") # 主函数 def workOn(): name = input("请输入贴吧名:") begin = int(input("请输入起始页:")) end = int(input("请输入终止页:")) # 对贴吧名name进行编码 kw = {"kw":name} kw = urllib.parse.urlencode(kw) # 拼接URL,发请求,获响应 for i in range(begin,end+1): # 拼接URL pn = (i-1)*50 baseurl = "http://tieba.baidu.com/f?" url = baseurl + kw + "&pn=" + str(pn) html = readPage(url) filename = "第" + str(i) + "页.html" writePage(filename,html) if __name__ == "__main__": workOn()
类写:
import urllib.request import urllib.parse class BaiduSpider: def __init__(self): self.headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"} self.baseurl = "http://tieba.baidu.com/f?" def readPage(self,url): # 请求并读取页面 req = urllib.request.Request(url,headers=self.headers) res = urllib.request.urlopen(req) html = res.read().decode("utf-8") return html def writePage(self,filename,html): with open(filename,"w",encoding="gb18030") as f: f.write(html) print("写入成功") def workOn(self): '''最终爬取''' name = input("请输入贴吧名:") begin = int(input("请输入起始页:")) end = int(input("请输入终止页:")) # 对贴吧名name进行编码 kw = {"kw":name} kw = urllib.parse.urlencode(kw) # 拼接URL,发请求,获响应 for i in range(begin,end+1): # 拼接URL pn = (i-1)*50 url = self.baseurl + kw + "&pn=" + str(pn) html = self.readPage(url) filename = "第" + str(i) + "页.html" self.writePage(filename,html) if __name__ == "__main__": spider = BaiduSpider() spider.workOn()
-
-
11.请求方式及实例
- GET
- 特点:查询参数在URL地址中显示
- 案例:抓取百度贴吧
- POST(在Request方法中添加data参数)
- urllib.request.Request(url,data=data,headers=headers)
data:表单数据以bytes类型提交,不能str - 处理表单数据为bytes类型
- 把Form表单数据定义为字典data
- urlencode(data)
- 转为bytes数据类型:bytes()
- 有道翻译案例
- 有道翻译返回的是json格式的字符串,如何把json字符串转换为Python中字典
import json
r_dict = json.loads(r_json)import urllib.request import urllib.parse import json # 请输入你要翻译的内容 key = input("请输入要翻译的内容:") # 把提交的form表单数据转为bytes数据类型 data = {"i": key, "from":"AUTO", "to":"AUTO", "smartresult":"dict", "client":"fanyideskweb", "salt":"1540373170893", "sign":"a5d9b838efd03c9b383dc1dccb742038", "doctype":"json", "version":"2.1", "keyfrom":"fanyi.web", "action":"FY_BY_REALTIME", "typoResult":"false" } # 字符串 i=python&from=auto.... data = urllib.parse.urlencode(data) data = bytes(data,"utf-8") # 发请求,获取响应 # url为POST的地址,抓包工具抓到的,此处去掉 _o url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule" headers = {"User-Agent":"Mozilla/5.0"} # 此处data为form表单数据,为bytes数据类型 req = urllib.request.Request(url,data=data,headers=headers) res = urllib.request.urlopen(req) html = res.read().decode("utf-8") # 把json格式字符串转换为Python中字典 r_dict = json.loads(html) print(r_dict) # 作业 :把翻译后的结果输出来 # 请输入要翻译的内容 :你好 # hello
- urllib.request.Request(url,data=data,headers=headers)
今日示例
Spyder下载