1.简单爬取
软件:Pycharm
两步创建完整项目
scrapy startproject 项目名称
scrapy startspider 爬虫的名称 网页的域名
下面步骤均在Terminal中执行
举例 | |
---|---|
创建项目 | scrapy startproject |
创建爬虫 | scrapy genspider baidu www.baidu.com |
import scrapy
from scrapy import Request
class DoubanSpider(scrapy.Spider)
name="douban"
allowed_domains = ['www.douban.com']
start_urls = ['https://xxx.xxx.com/xxx']
def parse(self.response)
# 用xpath获取电影名称的html路径
# 返回的类型是一个选择器列表
movie_selectorlist = response.xpath('//div[@class="hd"]/a/span[1]/text()')
# 将需要的文本提取出来
movies = movie_selectorlist.extract()
# 提取出来的是名称列表
# 对其进行遍历
for movie in movies:
item = {"movie_name":movie}
# 将item发送给ITEM PIPLINES
yield item
#上面是获取一页的,如果需要多页
# 获取“下一页”按钮的href
next_href = response.xpath("//span[@class="next"]/a/@href").get()
# 判断按钮是否存在,最后一页是没有次按钮的 有的next_href前面中存在“/”,拼接路径时注意不要重复和缺少
if next_href:
# 下一页的域名,拼接路径
next_url = 'https://xxx.xxx.com/xxx' + next_href
#将下一页的请求发送给本函数
yield Request(next_url,self.parse)
为方面界面美观,下面的执行代码简称为码
开始爬虫代码:
执行代码 | scrapy crawl 爬虫名称 |
---|---|
-o xx.json | 可加在码的后面,以json的格式保存在本地默认为当前项目路径下 |
-s CLOSESPIDER-PAGECOUNT=3 | 可加在码后,只爬取三页内容 |
-s CLOSESPIDER-TIMEOUT=3 | 可加在码后,3秒过后停止爬虫 |
ps:记得在项目设置中修改USER_AGENT和ROBOTSTXT_OBEY哟~~(滑稽脸)
2.设置代理
位置:项目名称/middlewares.py/XXDownloaderMiddleware(object)
在此路径下的process_request函数中可设置代理ip或代理池/用户代理
1 IP代理池
#将ip改为https://xxx.xxx.com/
request.meta["proxy"]="https://xxx.xxx.com/"
# 随机更换ip
url = ["https://xxx.xxx.com/","https://xxx.xxx.com/","https://xxx.xxx.com/"]
a = int(choice(range(len(url))))
request.meta['proxy'] = url[a]
2 请求头代理池
# 设置为某一请求头的用户代理
request.headers["USER_AGENT"] = "xxxxxxx"
# 随机更换
#####参照IP####
3.二次请求
获取某网站用户的具体信息
class XxxSpider(scrapy.Spider):
name="xxx"
allowed_domains = ["www.xxx.com"]
start_urls = ["http://www.xxx.com"]
def parse(self,response):
#在网站查找用户名的html属性
author_selectorlist = response.css("div.author)
for author_selector in author_selectorlist:
item = {}
src = author_selector.xpath("a[1]/img/@src").get()
if src:
item["pic_path"] = "http:" + src
yield item
# 提取用户信息的URL地址
user_url = "http"//www.xxx.com" + author.selector.xpath("a[1]/@href").get()
#发送个人页面请求
yield Request(user_url,callback=self.user_parse)
next_href = response.xpath("//ul[@class="pagination"]/li[last()]/a/@href").get()
if next_href:
next_url = "www.xxx.com" + next_url
yield Request(next_url,callback = self.parse) # 翻页
# 发送隔热页面请求后回调的方法
def user_parse(self,response):
item = {}
item["name"] = response.xpath("xxxx/xxx/text()").get()
item["sex"] = response.xpath("xxxx/xxx/text()").get()
yield item
4.POST请求
见到最多的还是登录页面
此处就用登录页面做示范
import scrapy
from scrapy import Request,FormRequest
class GswSpider(scrapy.Spider)
name = "gsw"
allow = ["www.xxxx.com"]
# 开始请求会执行的函数
def start_requests(self):
# 获取登录页面验证码的网址
captcha_url = "https://www.xxxx.com/xxx.xxx"
yield Request(captcha_url,callback=self.login)
def login(self,response)
# 将验证码图片数据鞋如本地文件
with open("captcha.png","wb")as f:
f.write(response.body)
#ydm 为导入的py文件,用来识别图片验证码的内容 需自行查找此类py文件
# 识别验证码的内容
code = ydm。get_code("captcha.png")
# 登录页面网址
login_url = "http://xxx.xxx.com/login.xxx"
formdata_dict = {
#name为输入账号的name属性
"name":"xxxx",
#password为输入密码的name属性
"password":"xxxxx",
}
yield FormRequest(login.url,formdata=formdata_dict,callback=self.after_login)
def after_login(self,response)
# 将登陆之后的页面以html的形式保存在本地
with open("result.html") as f:
f.write(response.body)
5.ajax
在middlewares.py下的DownloaderMiddleware中设置:
def __init__(self):
self.browser = Chrome(r'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')
在process_request()中:
def process_request(self,request:Request)
self.browser.get(request.url)
time.sleep(3) #线程挂起,等待浏览器加在
for i in range(100,100000,1000):
self.browser.execute_script("document.documentElement.scrollTop=%d"%i)
#滑轮自动向下翻页,每次1000px
time.sleep(2) # 等待加载
item文件中:
class AjaxXxxItem(scrapy.Item):
movie_name = scrapy.Field()
在爬虫文件中:
# 将items中的类导入
from ..items import AjaxXxxItem
class XxxSpider(scrapy.Spider):
name = 'xxx'
allowed_domains = ['movie.xxx.com']
# 在浏览器中抓取ajax网址
start_urls = ['https://movie.xxx.com/typerank?type_name=%E5%8F%A4%E8%A3%85&type=30&interval_id=100:90&action=']
def parse(self, response:HtmlResponse):
# with open("rank.txt",'wb') as f:
# f.write(response.body)
# print("写入成功!")
names_selectorlist = response.xpath('//div[@class="movie-content"]//div[@class="movie-name"]//a/text()')
for name in names_selectorlist.extract():
item = AjaxXxxItem()
item["movie_name"] = name
yield item
6. 结合Redis,分布爬取网站url
1. 爬取
首先需要在终端打开redis
此处用的是redis中的6379端口,密码为空,0号库
r = redis.Redis(host="localhost",port=6379,db=0)
class QiubaiSpider(scrapy.Spider):
name = "qiubai"
allowed_domains = ["www.xxxx.com"]
start_urls = ["https://www.xxx.com/xxx"]
def parse(self,response:HtmlResponse)
#设置redis中的key
keys = ""demo:url
# 当value为空时,将第一页的url加到redis中
if r.llen(keys) == 0:
r.lpush(keys,self.start_urls[0])
# 获取“下一页”按钮的href
next_href = response.xpath('//div[@class="col1"]/ul/li[last()]/a/@href').get()
if next_href:
next_url = "http://xxx.xxx.com" + next_href
r.lpush(keys,next_url)
yield Request(next_url,callback=self.parse)
2 运用redis
class QiubaiSpider(RedisSpider):
name = "qiubai"
redis_key = "demo:urls"
def parse(self,response:HtmlResponse):
print("具体的URL是:",response.url)
7.CrawlSpider
创建:(在Teminals中)
scrapy genspider -t crawl spider名称 域名
LinkExtractor构造方法中参数:
allow:指定正则表达式
restrict_xpaths:指定xpath规则
restrict_css:指定css规则
Rule参数介绍:
link_extractor参数:指定连接提取器
call_back参数:回调函数,指定解析器解析数据的规则
follow参数:是否将链接提取器继续作用到链接提取器提取的链接网页中,当callback为None时,默认为True
pip install scrapyd
pip install scrapyd-client
windows下:
虚拟环境的Scripts目录中添加文件:scrapyd-deploy.bat
虚拟环境的位置\Scripts\python.exe 虚拟环境的位置\Scripts\scrapyd-deploy %*
修改scrapy.cfg文件
[deploy:部署名称]
url = http://localhost:6800/
project = 项目名称
打包命令:
scrapyd-deploy 部署名称 -p 项目名称
操作scrapy爬虫的API:
开启爬虫
curl http://localhost:6800/schedule.json -d project=项目名称 -d spider=爬虫名称
停止爬虫
curl http://localhost:6800/cancel.json -d project=scrapy项目名称 -d job=运行ID
删除scrapy项目
curl http://localhost:6800/delproject.json-d project=scrapy项目名称
查看有多少个scrapy项目在api中
curl http://localhost:6800/listprojects.json
ps:注意:如果要远程访问scrapyd服务,则需要修改scrapyd的默认配置文件
在虚拟环境\Lib\site-packages\scrapyd\default_scrapyd.conf,将bind_address的值修改为0.0.0.0
8. Docker
在ubuntu下:
安装内核模块 | sudo apt-get install linux-image-extra-virtual |
---|---|
安装依赖 | sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common |
修改源:
参照:[https://blog.csdn.net/dty306034831/article/details/79188808]
不推荐第三步的更新软件(有点慢)
添加软件源的GPG秘钥 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
---|---|
向source.list添加Docker的软件源 | sudo add-apt-repository “deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable” |
安装Docker CE | sudo apt-get update 与sudo apt-get install docker-ce |
使用镜像:
搜索仓库 | sudo docker search centos(检查centos镜像是否存在) |
---|---|
使用pull命令下载镜像到本地 | sudo docker pull centos:latest下载centos镜像,latest为镜像的标签,表示最新的版本。 |
列出本地镜像 | sudo docker images |
删除本地镜像 | sudo docker rmi nginx(删除nginx镜像) |
基本语法:
1.使用create子命令创建容器
docker create [options] image [command] [arg…]
options为各种选项,image为镜像文件,command为要执行的命令
eg:从tomcat:latest镜像创建一个容器,并且命名为tomcat
sudo docker create --name tomcat tomcat:latest
2.使用run子命令创建容器
docker run [options] image [command] [arg…]
eg:从ubuntu:17.04镜像创建一个容器,创建成功之后,调用容器中的/bin/echo命令打印一行信息
sudo docker run ubuntu:17.04 /bin/echo “Hello,world.”
启动容器:
docker starty 已存在的容器名称
停止容器:
docker stop 要终止的容器名称
查看容器:
docker ps
查看所有容器 包括终止状态的
docker ps -a
删除容器:(已终止)
docker rm tomcat
使用网络:
以下命令通过-P选项为容器随机指定了一个端口来映射到容器的8080端口,启动容器
后用户就可以在外部网络中通过访问宿主机的映射端口访问到容器的8080端口了:
sudo docker run -d -P --name tomcat1 tomcat