Request简介及部分源码
class scrapy.http.Request():Request对象表示一个HTTP请求,由Spider生成,由Downloader执行。
常用的参数
url: 就是需要请求,并进行下一步处理的urlcallback: 指定该请求返回的Response,由那个函数来处理。
method: 请求一般不需要指定,默认GET方法,可设置为"GET", "POST", "PUT"等,且保证字符串大写
headers: 请求时,包含的头文件。一般不需要。
meta: 比较常用,在不同的请求之间传递数据使用的。字典dict型
request_with_cookies = Request(
url="http://www.example.com",
cookies={'currency': 'USD', 'country': 'UY'},
meta={'dont_merge_cookies': True}
)
encoding: 使用默认的 'utf-8' 就行。
dont_filter: 表明该请求不由调度器过滤。这是当你想使用多次执行相同的请求,忽略重复的过滤器。默认为False。
errback: 指定错误处理函数
Response简介及部分代码
class scrapy.http.Response():Response对象表示一个HTTP响应;由Downloader生成,由Spider处理。
常用参数
status: 响应码
_set_body(body): 响应体
_set_url(url):响应url
self.request = request
三种scrapy模拟登陆策略
注意:模拟登陆时,必须保证settings.py里的 COOKIES_ENABLED (Cookies中间件) 处于开启状态
COOKIES_ENABLED = True 或 # COOKIES_ENABLED = False
1、发送POST请求--登录人人网。post请求要重写 重写start_requests方法,再里面做post请求
import scrapy
#模拟登录
class Renren1Spider(scrapy.Spider):
name = 'renren1'
#这些都可以注释掉
# allowed_domains = ['renren.com']
# start_urls = ['http://renren.com/']
def start_requests(self):
#url = "http://www.renren.com/"#不能用这个地址
#用下面的地址才能登录,下面的地址不错各种校验
url = "http://www.renren.com/PLogin.do"
# FormRequest 是Scrapy发送POST请求的方法
yield scrapy.FormRequest(
url=url,
formdata={"email":"[email protected]","password":"afu123456"},
callback=self.parse
)
def parse(self, response):
print(response.text)
2.模拟登陆--人人网登录案例
正统模拟登录方法:首先发送登录页面的get请求,获取到页面里的登录必须的参数。然后和账户密码一起post到服务器,登录成功。使用Scrapy抓取网页时,如果想要预填充或重写像用户名、用户密码这些表单字段, 可以使用 FormRequest.from_response() 方法实现。
import scrapy
# 正统模拟登录方法:
# 首先发送登录页面的get请求,获取到页里的登录必须的参数
# 然后和账户密码一起post到服务器,登录成功
class Renren2Spider(scrapy.Spider):
name = 'renren2'
allowed_domains = ['renren.com']
#第一次请求,正常的get请求
start_urls = ['http://www.renren.com/']
def parse(self, response):
print("------------0----------url==", response.url)
#模拟登录,第二次请求
yield scrapy.FormRequest.from_response(
response,
formdata={"email": "[email protected]", "password": "afu123456"},
callback = self.login_sucess
)
def login_sucess(self,response):
url = response.url
print("------------1----------url==",url)
#如果登录成功后请求郑爽的页面
url = "http://www.renren.com/881820831/profile"
yield scrapy.Request(url,callback=self.new_page)
def new_page(self,response):
url = response.url
print("------------2----------url==", url)
with open("郑爽.html","w",encoding="utf-8") as f:
f.write(response.text)
3. 使用cookie--登录人人网
使用浏览器访问登陆成功并且抓包找到cookie拷贝后使用正则表达式批量处理整理成字典键值对(一定可以登陆前两种只适合没有cookie验证的)
import scrapy
class Renren0Spider(scrapy.Spider):
name = 'renren0'
allowed_domains = ["renren.com"]
start_urls = (
'http://www.renren.com/964604530',
)
cookies = {
"anonymid":"jf3oljey-omh3t8",
"depovince":"BJ"
}
def start_requests(self):
for url in self.start_urls:
# yield scrapy.Request(url, callback = self.parse)
# url = "http://www.renren.com/410043129/profile"
yield scrapy.FormRequest(url, cookies=self.cookies, callback=self.parse_page)
def parse_page(self, response):
print("===========" + response.url)
with open("阿福主页.html", "w",encoding="utf-8") as filename:
filename.write(response.text)
数据存入mongodb--把电影数据存入mongodb
配置settings.py 1、不遵循爬虫协议;2、配置mongo相关配置;3、禁用cookie;4、配置浏览器身份;# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'douban (+http://www.yourdomain.com)'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
#下面是配置mongodb数据库的信息 mongo 主机
MONGO_HOST = '127.0.0.1'
#mongo 端口
MONGO_PORT = 27017
#mongo 数据存放数据库库名称
MONGO_DBNAME = "douban"
#mongo 数据存放的表名称
MONGO_SHEETNAME = "movetop250"
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
#DoubanMongodbPipeline在process_item函数中不返回数据,DoubanPipeline级别低的将不会收到数据。ITEM_PIPELINES = {
# 'douban.pipelines.DoubanPipeline': 300, 'douban.pipelines.DoubanMongodbPipeline': 301,}#创建客户端
client = pymongo.MongoClient(host=host,port=port)#得到或者创建数据库对象
mydb = client[dbname]
#得到或者创建表
self.post = mydb[sheetname]
再pycharm中使用mong#客户端
无安全认证:client = MongoClient('localhost', 27017)
client = MongoClient('mongodb://localhost:27017/数据库名称')
client = MongoClient('mongodb://localhost:27017/test1')
有安全认证:
client = MongoClient('mongodb://用户名:密码@localhost:27017/数据库名称')
client = MongoClient('mongodb://t1:123@localhost:27017/test1')
类database
获得数据库test1 db=client.test12.4 类collection
主要方法如下:
• insert_one
• insert_many(insert)
• update_one
• update_many(update)
• delete_one
• delete_many(delete)
• find_one
• find
设置下载中间件--1.随机User-Agent
获取user-aget的网址:https://blog.csdn.net/tao_627/article/details/42297443
在settings.py文件配置User-Agent列表
DOWNLOADER_MIDDLEWARES = {# 'douban.middlewares.DoubanDownloaderMiddleware': 543,
'douban.middlewares.RandomUserAgent': 543,
}
在middlewares.py文件中创建RandomUserAgent类重写process_request方法
from scrapy import signals
from douban.settings import USER_AGENTS
import random
#设置随机浏览器User-Agent
class RandomUserAgent(object):
def process_request(self,request,spider):
#得到浏览器标识列表
user_agent = random.choice(USER_AGENTS)
#打印取出随机的浏览器标识
print("user_agent==",user_agent)
request.headers.setdefault("User-Agent",user_agent)
设置下载中间件--2.动态代理
快代理免费代理:https://www.kuaidaili.com/free/inha/
在settings.py文件配置代理服务器列表PROXIES4.1.1 配置代理服务器列表PROXIES
#代理服务器
PROXIES = [
{"ip_port" :"117.48.201.187:16818", "user_passwd" : "trygf521:a4c4avg9"},#私立ip,需要账号授权
{"ip_port" :"120.24.171.107:16818", "user_passwd" : "trygf521:a4c4avg9"},#私立ip,需要账号授权
{"ip_port" :"114.113.126.87:80", "user_passwd" : None},#这些是不需要验证的
]
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
# 'douban.middlewares.DoubanDownloaderMiddleware': 543,
'douban.middlewares.RandomUserAgent': 542,
'douban.middlewares.RandomProxy': 545,
}
在middlewares.py文件中创建。
Scrapy代理IP、Uesr-Agent的切换都是通过DOWNLOADER_MIDDLEWARES进行控制,我们在settings.py同级目录下创建middlewares.py文件,包装所有请求。
from scrapy import signals
from douban.settings import USER_AGENTS
from douban.settings import PROXIES
import random
#动态代理类
class RandomProxy(object):
def process_request(self,request,spider):
proxy = random.choice(PROXIES)
if proxy['user_passwd'] is not None:
print("==============有账号和密码proxy========================", proxy)
url = "http://%s@%s" % (proxy['user_passwd'], proxy['ip_port'])
print("url=====================",url)
request.meta['proxy'] = url
else:
print("=============没有账号和密码proxy======================", proxy)
url = "http://%s" % proxy['ip_port']
print("url=====================", url)
request.meta['proxy'] = url
return None#可写可不写
禁用cookies
除非特殊需要,禁用cookies,防止某些网站根据Cookie来封锁爬虫。#禁用cookies
COOKIES_ENABLED = False
设置下载延迟
#设置延迟下载DOWNLOAD_DELAY = 3