1.概念、工具和HTTP
- 什么是爬虫
- 模拟客户端发送网络请求,获取响应,按照规则提取数据
- 爬虫的数据去哪了
- 展示到网页上(百度新闻,今日头条)
- 进行分析,从数据中寻找规律(指数网站:百度指数)
- 买卖数据
- 流量
- 需要的软件和环境
- python3
- pycharm编辑器
- chrome浏览器-分析网络请求
- 浏览器的请求
- url:检查→network
- 浏览器请求url地址
- 爬虫请求url地址
- HTTP和HTTPS
- 超文本传输协议:客户端和服务端约定
- HTTPS:HTTP+SSL(安全套接字层)--更安全一点
- HTTP协议之请求
- 请求行
- 请求头
- USER-AGENT:服务器据此判断访问的是什么浏览器,
- Cookie:用来存储用户信息,每次请求会携带上发送给对方
- 请求体
- get:没有请求体,把数据放在url中
- post:登录注册,可以携带比get多很多的信息
- request header
-
Accept:文本的格式
-
Accept-Encoding:编码格式
-
Connection:长链接 短链接
-
Cookie:验证用的
-
Host:域名
-
Referer:标志从哪个⻚页⾯面跳转过来的
-
User-Agent:浏览器器和⽤用户的信息
-
- 爬虫只能爬取用户能访问到的数据
- 爬虫的分类
- 通用爬虫:搜索引擎
- 聚焦爬虫:目标明确,增量式
- 静态数据
- 动态数据:JS代码,加密JS,
- 爬虫工作原理
- 需要抓取的URL地址
- 使用python代码发送请求获取数据----GO语言也行--requests
- 解析获取到的数据----找到新的URL(第一步)XPATH,BS4
- 数据持久化,保存到本地,数据库
- IP分类
- 透明IP:服务器知道我们的真实IP
- 匿名IP:服务器不知道我们真实的IP,但是知道我们在使用代理
- 高匿IP:服务器不知道我们的真实IP,也不知道我们使用了代理
2.requests模块的学习
- 安装
- pip install requests
- 发送get,post请求,获取响应
- response = requests.get(url)
- response = requests.post(url,data={请求体的字典})
- ②response.text:如果出现乱码,在前面加一行response.encoding = "utf-8"
- ①response.content.decode("utf-8") -----解码或者改成gbk解码
- 发送带header的请求
- headers = {"User-Agent":"xxx","Referer":"xxx",}
- response = requests.post(url,data={请求体的字典},headers= headers)
- response = requests.get(url,headers= headers)
- response.request.url
- response.request.headers
- response = requests.post(url,data={请求体的字典},headers= headers,timeout=3)---需要加异常捕获
- response = request,,headers= headers)
- retrying模块学习----重试
- pip install retrying----安装
- from retrying import retry
- @retry(stop_max_attempt_number=3)-------装饰器,执行几次
- cookie相关的请求
- cookie放在headers里面
- cookie存成字典,用requests.get(url,cookies=cookie_dict) 先发送post请求,获取cookie,带上cookie请求页面(会话维持 )
- session = requests.session()
- session.post(url,data,headers)
- session.get(url,headers)
- 优点
- 简单易用、
- url自动转义
- 支持python2,python3
- 药智网登录验证import requests
-
class RequestSpider(object): def __init__(self): url = "https://www.yaozh.com/login" headers = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser) ', # 'Cookie':'', } # 保存Cookie session = requests.Session() # 代理 proxy = { # 'http': '117.88.5.125:3000', # 'https':'117.88.176.110:3000', } login_form_data = { 'username': '', 'pwd': '', 'formhash': '', 'backurl': '', } # 忽略证书认证,登录 self.response = session.post(url=url, data=login_form_data, headers=headers, verify=False) # 用保存的cookie登录 url = 'https://www.yaozh.com/member/' self.data = session.get(url=url,headers=headers,verify=False).content.decode('utf-8') # self.response = requests.get(url=url, proxies=proxy, headers=headers, verify=False) def run(self): # 1.请求头 request_headers = self.response.request.headers print(request_headers) # 2.响应头 response_headers = self.response.headers print(response_headers) # 3.响应状态码 code = self.response.status_code print(code) # 4.请求的cookie request_cookie = self.response.request._cookies print(request_cookie) # 5.响应的cookie response_cookie = self.response.cookies print(response_cookie) # 6.数据 # data = self.response.content.decode('utf-8') data = self.data print(data) with open('yaozhi.html', 'w', encoding='utf-8') as f: f.write(data) RequestSpider().run()
3.数据的提取方法
- json--数据交换格式
- import json
- json.loads(json字符串):json转str
- json.dumps(python字典):str转json字符串(文件写入)
- json.dumps(ret,ensure_ascII=False):数据直接显示中文,不再以ASCII码方式显示
- 主要逻辑
- start_url
- 发送请求,获得响应
- 提取数据
- 保存
- 构造下一页url地址,循环2-5步
- Xpath:提取数据
- /html/a:选择标签
- //:任意节点开始
- //div[@class="xxx"]:选择某个值
- a/@class:选择class的值
- a/text():获取a下的文本
- a//text():获取a下的所有文本
- lxml
- pip install lxml
- from lxml import etree
- element = etree.HTML("html字符串")
- element.xpath("")
- 正则表达式
- BS4
3.数据的存储方法
- MongoDB
- redis
- 启动服务
- redis-server.exe redis.windows.conf
- 如果出现错误
- redis-cli.exe
- shutdown
- exit
- redis-server.exe redis.windows.conf
- 启动客户端
- redis-cli
- 切换数据库
- select 1
- 字符串操作
- 查询所有Keys:keys *
- 单独写入:set one ''1"
- 查询:get one
- 清空所有数据库:flushall
- 清空当前数据库:flushdb
- 多个写入:mset one 1 two 2 three 3
- 查询多个 :mget one two three
- 设置过期时间(例如3秒):setex one 3 'abc'
- 追加:append two "345"
- 替换:set one 123
- hash对象
- 写入哈希对象:hset person "张三"
- 给person对象增加年龄属性:hset person age "18"
- 查询person对象的属性:hget person age
- 同时写入多个属性(先创建对象):hmset person birth 2000 gender ture
- 同时查看多个属性:hmget person birth gender
- 查询person对象的所有属性:hkeys person
- 删除属性:hdel person age
- 查询person对象所有的values:hvals person
- list
- 创建列表(左):lpush one 1 2 3 4 5
- 创建列表(右):rpush one 1 2 3 4 5
- 查询列表:lrange one 0 -1
- 修改:lset one 5 "123"
- 删除 :lrem one 0 b
- 删除:lrem one 1 1
- 删除 :lrem one -1 "123"
- set
- 增加集合元素:sadd setone 1 2 3 4
- 查看集合元素:smembers setone
- 删除集合元素:srem setone 1 2
- 判断集合元素是否存在:sismember one 0
- 没有修改
- zset:有序集合
- 增加元素:zadd one 1 a
- 查看所有元素:zrange one 0 -1
- 查看权重区间元素:zrangebyscore one 2 3
- 查看权重:zscore one a
- 删除元素:zrem one a
- 根据权重范围删除元素:zremrangebyscore one 2 3
- 与python的交互
- 导入:import redis
- 链接数据库:client = redis.StrictRedis(host='127.0.0.1',port=6379)
- 设置key:key = 'pyone'
- string增:result = client.set(key,'1')
- string删:result = client.delete(key)
- string改:result = client.set(key,'2')
- string查:result = client.get(key)
- 查看所有的key:result = client.keys(key)
- 启动服务
- mysql
4.Scrapy框架爬虫实战
- 引擎从爬虫获得整个框架的初始 请求
- 引擎把初始请求发送给调度器
- 调度器返回给引擎下一个要爬取的请求
- 通过下载器中间键,引擎将请求传递给下载器
- 下载器将请求转换成响应后,通过下载器中间键在传递给引擎
- 引擎拿到响应,通过爬虫中间件将响应发送给爬虫
- 爬虫解析完响应,通过爬虫中间件,将新的请求和数据项发送给引擎
- 引擎将数据项发送给数据项管道,新的请求重复前面的过程
- 数据量比较多,公司后期要求cc会自己编写一个框架爬取自己的数据
- 安装
- pip install scrapy
- 创建项目
- scrapy startproject 项目名
- 调试终端
- scrapy shell www.baidu.com
- 生成爬虫
- scrapy genspider 爬虫名 网址
- 运行爬虫
- scrapy crawl 爬虫名
- scrapy crawl 爬虫名 -o 名字.json
- scrapy crawl 爬虫名 -o 名字.csv
- 返回项目所有spider
- scrapy list
- 存储打开网页
- scrapy view 网址
- 直接通过爬虫文件名运行
- scrapy runspider 爬虫名
- 爬虫
- 下载器中间键
- 按照优先级被调用,requests从引擎向下载器传递时数字小的先执行,下载器向引擎传递,数字大的先执行。
- process_request(request,spider):对请求做修改,User-agnent,代理等
- process_response(request,response,spider):对响应进行修改
- 例子1
-
import random class RandomUA(): def __init__(self): self.user_agent = [ 'User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36', 'User-Agent:Opera/9.80 (Windows NT 6.1; WOW64; U; en) Presto/2.10.229 Version/11.62', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36', ] def process_request(self, request, spider): request.headers['User-Agent'] = random.choice(self.user_agent) def process_response(self, request, response, spider): response.status = 201 return response
-
- 例子2