1、网络爬虫
定义 :网络蜘蛛、网络机器人,抓取网络数据的程序
总结 :用Python程序去模仿人去访问网站,模仿的越逼真越好
爬取数据的目的 :通过有效的大量数据分析市场走势、公司决策
2、企业获取数据的方式
公司自有数据
第三方数据平台购买
数据堂、贵阳大数据交易所
爬虫爬取数据
市场上没有或者价格太高,利用爬虫程序爬取
3、Python做爬虫优势
请求模块、解析模块丰富成熟,强大的scrapy框架
PHP :对多线程、异步支持不太好
JAVA :代码笨重,代码量很大
C/C++ :虽然效率高,但是代码成型很慢
4、爬虫分类
通用网络爬虫(搜索引擎引用,需要遵守robots协议)
http://www.taobao.com/robots.txt
搜索引擎如何获取一个新网站的URL
网站主动向搜索引擎提供(百度站长平台)
和DNS服务网(万网),快速收录新网站
聚焦网络爬虫
自己写的爬虫程序:面向主题的爬虫、面向需求的爬虫
5、爬取数据步骤
确定需要爬取的URL地址
通过HTTP/HTTPS协议来获取相应的HTML页面
提取HTML页面有用的数据
所需数据,保存
页面中有其他的URL,继续 第2步
6、Anaconda和Spyder
Anaconda :开源的Python发行版本
Spyder :集成开发环境
Spyder常用快捷键:
注释/取消注释 :ctrl + 1
保存 :ctrl + s
运行程序 :f5
自动补全 :Tab
本来是打算用Spyder的但是感觉没有Pycharm好用
微软的VScode也不错 说实话 Pycharm好用但是在爬虫方面 运行效率稍差
7、Chrome浏览器插件
如果可以直接在谷歌商店点击添加就可以
Mac推荐高效免费VPN: VPN Plus
安装步骤
右上角 - 更多工具 - 扩展程序
点开右上角 - 开发者模式
把插件 拖拽到 浏览器页面,释放鼠标,点击 添加扩展...
我个人用的是Mac系统 之前是Ubuntu 不过都差不多 一下是Mac安装Fiddler
1、安装Mono .net虚拟机
Mono下载地址:
https://www.mono-project.com/download/stable/
安装完成后,在在Terminal里执行以下命令:
/Library/Frameworks/Mono.framework/Versions//bin/mozroots --import —sync
注意:是指Mono版本号
我的是 5.16.0
/Library/Frameworks/Mono.framework/Versions/5.16.0/bin/mozroots --import —sync
将mono添加到环境变量 默认自动添加
export MONO_HOME=/Library/Frameworks/Mono.framework/Versions/5.16.0
export PATH=PATH:MONO_HOME/bin
2.下载Fiddler.zip压缩文件
从Fiddler官网https://www.telerik.com/download/fiddler下载fiddler-mac.zip的压缩包。
解压压缩包
在解压后的文件内运行以下命令
如果报错运行一下命令 等待时间可能会久一点
sudo mono --arch=32 Fiddler.exe
我是用的sudo mono --arch=32 Fiddler.exe 这个命令
因为我用sudo mono Fiddler.exe 命令会报错
并且我将 fiddler的绝对路径 添加了自定义环境变量
vi ~/.bash_profile
alias fiddler="sudo mono --arch=32 绝对路径/Fiddler.exe"
source .bash_profile
fiddler 这样就可以直接在终端运行Fiddler了
顺便说一下 Mac下的apt-get包管理工具
Homebrew
官网: https://brew.sh/index_zh-cn
安装:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装成功后可以使用brew安装软件包 具体内容看官网 有详细介绍
安装 mysql
brew install mysql
安装MongoDB
brew install mongodb
安装Redis
brew install redis
2、插件介绍
Proxy SwitchOmega :代理切换插件
Xpath Helper :网页数据解析插件
JSON View :查看json格式的数据(好看)
8、Fiddler抓包工具
抓包工具设置
Tools->options->HTTPS->...from browers only
connections :设置端口号 8888
设置浏览器代理
Proxy SwitchOmega -> 选项 -> 新建情景模式 -> HTTP 127.0.0.1 8888 -> 应用选项
浏览器右上角图标 -> AID1806 -> 访问百度
当然Mac下有更好抓包工具 比如 Charles
可惜是收费软件 之前的破解版都被和谐了
感兴趣的朋友可以去了解一下 还是非常强大的
9、WEB
HTTP和HTTS
HTTP :80
HTTPS :443,HTTP的升级版,加了一个安全套接层
GET和POST
GET :查询参数都会在URL上显示出来
POST:查询参数和需要提交数据是隐藏在Form表单里的,不会再URL地址上显示
URL :统一资源定位符
https:// item.jd.com :80 /26809408972.html #detail
协议 域名/IP地址 端口 访问资源的路径 锚点
4、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
# response为响应对象
response = urllib.request.urlopen("http://www.baidu.com/")
html = response.read().decode("utf-8")
print(html)
重构User-Agent
不支持重构User-Agent :urlopen()
支持重构User-Agent
urllib.request.Request(添加User-Agent)
urllib.request.Request("网址",headers="字典")
User-Agent是爬虫和反爬虫斗争的第一步,发送请求必须带User-Agent
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())
利用Request()方法构建请求对象
利用urlopen()方法获取响应对象利
用响应对象的read().decode("utf-8")获取内容
响应对象response的方法
read() :读取服务器响应的内容
getcode()
作用
返回HTTP的响应码
print(respones.getcode())
200 :成功
4XX :服务器页面出错
5XX :服务器出错
geturl()
作用 :返回实际数据的URL(防止重定向问题)
#拼接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)
urllib.parse模块
urlencode(字典) ## 注意:参数一定要为字典
urlencode({"wd":"美女"})
wd=%e8.......
tedu = {"wd":"巴黎IT"} //我自己的网站 过段时间上线
请输入你要搜索的内容:美女
保存到本地文件 :美女.html
key = urllib.parse.quote("字符串")
baseurl = "http://www.baidu.com/s?wd="
key = input("请输入要搜索的内容:")
#进行quote()编码
key = urllib.parse.quote(key)
url = baseurl + key
print(url)
#拼接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)
百度贴吧数据抓取
要求:
1、输入要抓取的贴吧名称
2、输入爬取的起始页和终止页
3、把每一页的内容保存到本地
第1页.html 第2页.html ... ...
步骤:
找URL规律,拼接URL
第1页:http://tieba.baidu.com/f?kw=??&pn=0
第2页:http://tieba.baidu.com/f?kw=??&pn=50
第3页:http://tieba.baidu.com/f?kw=??&pn=100
.....
第n页:pn=(n-1)*50
获取网页内容(发请求获响应)
保存(本地文件、数据库)
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
def main():
while True:
# 请输入你要翻译的内容
key = input("(exit退出)有道翻译::")
if key == "exit":
break
elif not key:
print("")
continue
# 把提交的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)
# 把翻译后的结果输出来
# 请输入要翻译的内容 :你好
# hello
result = r_dict['translateResult'][0][0].get("tgt", '您输入的信息未找到')
print("=" * 50)
print(result)
print("=" * 50)
if __name__ == "__main__":
main()