爬虫笔记

框架 pyspider
pyspider 启动
callback 回调
self.crawl 生成一个爬取任务,加入到待爬取的队列

@every 告诉调度器 这个方法 每天执行一次

@config 告诉调度器 这个request请求 过期时间为10天

解析数据 re bs4 xpath pyquery

phantomjs 无界面浏览器
之后即可在crawl()中使用fetch_type = 'js'参数,
self.crawl(url, callback = self.last_page, fetch_type = 'js')

这是因为https协议需要对证书进行验证导致,解决方法是,
在crawl()方法中使用validate_cert参数,
self.crawl(url, callback = self.last_page, validate_cert = False)

第一种启动方式 runspider
shell
第二种 startproject
import scrapy
命令行 scrapy startproject baidu
cd baidu
scrapy genspider baidu_spider yuming
项目命令
gensipder scrapy genspider
list scrapy list

scrapy crawl

一 创建项目 scrapy startproject douban_movie
二 创建spider模板文件 scrapy genspider movie_spider douban.com
三 定义items数据 定义要抓取的字段数据
四 开始编写spider文件
scrapy crawl 执行

scrapy里面的xpath返回的是一个selector对象
extract()方法 把selector对象序列化为一个字符串 列表
修改 settings里面的为False
在 main文件中 execute(['scrapy','crawl','douban_spider'])

在pipeline类里面 process_item是默认被调用的
open_spider与close_spider
在 settings文件里面进行说明 取消注释 进行运行
xpath css re
//;/;./;
.;..
@
text
string
contains cantains(@id, "note-")
a::attr(href) 选取a标签的属性值
a[href^='http'] 以http开头
a[href*='job'] 包含job

scrapy shell
scrapy shell http://www.baidu.com

start_requests

spider类
name 必须定义
start_urls 没有特别定制url的时候 要写
start_requests
parse 当继承spider类的时候 必须定义
class TnnctItem(scrapy.Item):
work_name = scrapy.Field()

extract_first() 第一个

from scrapy.cmdline import execute
execute(['scrapy',''crawl',''])
在pipeline类里面,process_item默认调用的
日志 logging
调试信息 debug
一般信息 info
警告 warning
error
critical严重错误
如何设置log的级别 --nolog
1 在终端 通过参数 指定 -L
2 在setting文件里面设置
LOG_FILE = 'tencent.log'
LOG_LEVEL = INFO
LOG_ENABLED True
'utf-8'
LOG_FILE None

scrapy genspider -t crawl tencent_spider tencent.com

LinkExtractor类 提取链接
allow 满足括号内的正则表达式的url会被提取,如果是空 则全部被匹配
deny 满足括号内的正则表达式的url一定不提取 优先级高于allow
allow_domains
deny_domains

Rule
rules元组
link_extractor提取链接 allow
CrawlSpider 只需定义需要的url的规则

Request
dont_filter 不过滤
start_urls里面的地址不会被过滤,但其他的相同url会过滤 默认 dont_filter=True则不过滤

Response
status 状态码

模拟登录 post请求 FormRequest
if成功 添加return,不再执行后面的语句

F10 单步跳过 不进入方法内部
F11 跳进函数内部

漫画网站
1 请求页面 解析返回msg请求所需的参数,以及dm5_key的js代码
2 执行js代码 拿到key 模拟请求获取msg的值
3 执行msg 拿到图片地址

中间件 主要是用来更换 代理 更换cookie 更换ua 重试
下载器
request.headers
request.meta

第一种 python模拟js逻辑
第二种 execjs 直接执行js代码
第三种 selenuim 简单

app抓包分析

图片下载器

pyexecjs compile解析js语句 eval执行
import execjs
execjs.eval("'red yellow blue'.split(' ')")
['red', 'yellow', 'blue']

ctx = execjs.compile("""
... function add(x, y) {
... return x + y;
... }
... """)
ctx.call("add", 1, 2) 调用js函数
开了抓包,要写 verity = False 会被监听,不需要验证
HTTPERROR_ALLOWED_CODES = [403]
parse.quote() 编码
parse.unquote()

Docker 系统管理
环境配置
虚拟机的缺点:1资源占用过大;2步骤比较多
linux容器 1资源占用非常少 只是一个进程而已 不是一个完整的系统资源

Docker 应用容器引擎 一个容器的封装 让程序使用起来更加方便 有很多方便的接口
让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,
然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口。
安装命令 1 sudo apt-get install docker.io
2 wget -q0- https://get.docker.com/ | sh
安装完成之后 通过 sudo docker run hello-world 来测试是否安装成功
添加用户组
sudo usermod -aG docker $USER
镜像加速
打开 找到镜像加速服务
https://dev.aliyun.com/search.html 来到个人中心在产品里面 搜索 镜像加速服务
打开 /etc/docker/daemon.json 没有就创建
写入
{
"registry-mirrors":["https://8aqqf23r.mirror.aliyuncs.com"]
}
镜像和容器的关系,类和实例
镜像是静态的定义,容器是镜像运行时的实体
容器可以被创建、启动、停止、删除、暂停等。
镜像 容器 仓库
特殊的文件系统,提供运行时候的程序 库 资源 配置文件 还包含配置参数 环境变量 用户等
不包含动态数据
不会被改变
获取镜像
docker pull ubuntu:16.04
基本命令
查看本地已经存在的镜像 docker image ls
删除镜像 docker rmi imageID -f
docker run -i -t ubuntu:latest
-i insert
-t terminal 可以写一起 -it
查看容器 docker ps 只显示正在运行的
docker run ubuntu:latest echo 'welcome to docker...'
docker run --name
docker pull nginx:latest
docker run nginx:latest
端口转发 映射
docker run -p 80:80 nginx:latest
docker run -p 80:80 -d nginx:latest
curl 127.0.0.1:80
docker stop nameID
docker rm nameID 删除容器 -f
docker rmi nameID 删除镜像 -f
结果 类似于日志
查看容器的日志信息
docker log contianerID

定制镜像
docker build
定义一个Dockerfile的文件
vim Dockerfile
FROM nginx
RUN echo '<h1>Welcome to Docker</h1>' > /usr/share/nginx/html/index.html
docker build -t my_nginx .
docker image ls
docker run -it -p 80:80 my_nginx:latest
curl http://127.0.0.1:80 访问
FROM 指定基础镜像
RUN 执行命令
COPY 复制本地内容到容器内部
CMD 启动容器的命令 默认的命令行参数
ENTRYPOINT 指定容器启动程序以及参数



spider 5000
scrapyd 6800
scrapyd 部署
scrapyd 官方提供的一个爬虫管理工具

安装 sudo pip install scrapyd
端口转发
scrapyd
cd /anaconda3/lib/python3.6/site-packages/scrapyd
bind_address = 127.0.0.1 => 0.0.0.0

部署项目
pip install scrapyd-client
发布项目到scrapyd服务
1 打开scrapy.cfg文件 更改url ip地址
指的是 你要推送到的scrapyd服务的地址

上传
scrapyd-deploy <target> -p <project> --version <version>
cd /Users/liubosong/Desktop/Project/baidu
scrapyd-deploy -p baidu

scrapyd API接口
启动爬虫 curl http://localhost:6800/schedule.json -d project=baidu -d spider=baidu_spider
停止爬虫 curl http://localhost:6800/cancel.json -d project=baidu -d job=jobid
删除项目 curl http://localhost:6800/delproject.json -d project=baidu
列出当前项目的爬虫 curl http://localhost:6800/listspider.json?project=project_name
列出当前项目的爬虫 全部的 curl http://localhost:6800/listspider.json

docker部署
WORKDIR /code 工作目录

安装依赖环境
FROM python:3.6
RUN pip install scrapy
ADD命令 在 COPY命令上 多加了一些命令
commit
仓库
官方的仓库
私有仓库 docker-registry
pull下载 push上传
docker tag 修改

docker login
docker push wangxianii/tencent_spider:v2
docker run -d tencent_spider:v2 在后台执行
docker exec -it e36c42ba7346 bash 进入

pyexecjs

os.popen('node index.js {}')
第一个参数 是js的路径
第二个参数是 执行js文件的路径
第三个 命令行参数

js代码
var _ = process.argv.splite(2);
console.log(getParam(_[0]));

scrapy_redis 基于scrapy框架的组件 用于开发scrapy项目的分布式和部署
特点 利用redis数据库 来保存队列和去重
只是一个组件
scrapy_redis 提供的组件 Scheduler Duperfilter Pipeline Spider
爬取队列 调度器 过滤 共用队列
net 网络 端口转发 6379

redis数据库
基本数据类型
字符串
set mykey : value
get mykey
append 字符串后面添加字符串
散列/哈希
列表
lpush添加
lrange查看
lpop删除
llen
lindex
集合
sadd myset value
scard 查看set的值
smember key查看全部元素
有序集合
zadd 添加
zrangebyscore myset 0 10 查看集合某个范围内的元素
zcount set 0 10
scrapy_redis 是基于scrapy框架的组件 用于开发scrapy项目的分布式和部署
特点 利用redis数据库 来保存队列 和 去重
scrapy_redis 提供的组件 Scheduler Dupefilter Pipeline Spider
爬取队列 在调度器里面 spider共用队列
把放在本机队列中的数据 改放到redis数据库中,共享
调度器
过滤
git clone https://github.com/rmax/scrapy-redis.git
Python3.x,更新当前pip python3 -m pip install --upgrade pip
需求分析
1 农产品
基于scrapy redis和mongodb的分布式爬虫
www.nongnet.com/xinxi/
//a[text()="下一页"]/@href

基于scrapy_ redis 和MongoDB的分布式微博爬虫
需求描述
1.自动登录微博,获取登录成功之后的Cookie数据,存放到redis数据库
2.自动抓取微博用户的个人资料及微博信息,包括但不限于文字图片等数据.
3.对抓取结果按照不用类型,分类存档
4.对抓取过程中遇到的各类异常分析,并处理,保证程序的高可用.
scrapy_redis常用组件
keys *
type dmoz:dupefilter
lrange dmoz:items 0 2 查看数据库内的数据
smembers dmoz:dupefilter
调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler"
去重 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
flushdb 清空数据

settings.py
# 指定scrapy_redis的调度器
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
# 指定scrapy_redis的去重
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
# 在redis中 保持 用到的队列 会继续
SCHEDULER_PERSIST = True
# redis数据库的配置
REDIS_HOST = '127.0.0.1'
REDIS_POST = 6379
REDIS_PARAMS = {'password': '0000', }

tencent_spider.py 主文件的修改
导入 RedisSpider
from scrapy_redis.spiders import RedisSpider
继承
class TencentSpiderSpider(RedisSpider):
设置redis_key键 以便添加 url地址
redis_key = 'tencent:start_urls'
redis-cli
lpush tencent:start_urls 'http://...'
延时请求
怎样使用scrapy-redis? --》 redis键名介绍
1、
“项目名:items”
list类型,保存爬虫获取到的数据item
内容是json字符串
2、
“项目名:dupefilter"
set:
类型,用于爬虫访问的URL去重
内容是40个字符的url的hash字符串
3、
“项目名: start_urls"
List类型,用于获取spider启动时爬取的第一个url
4、
“项目名:requests”
zset
类型,用于scheduler调度处理requests
内容是request对象的序列化字符串
''.join(response.xpath(...))

[@class=""]属性
[text()=""]方法
原文地址:https://www.cnblogs.com/liubosong/p/10340222.html