今日是2020.01.01,好日子。写一个文章记录一下scrapy的常用操作。
开始安装2020,新的一年到来了。
>>>pip install 2020
Collecting 2020
Downloading https://files.pythonhosted.org/packages/2020.whl (2020kB)
|████████████████████████████████| 2020kB 2020kB/s
Installing collected packages: 2020
Successfully installed 2020-1.0.0
1. 为每一个请求添加请求头
1.1 方法一(直接在settings文件中添加)
在settings文件,取消注释DEFAULT_REQUEST_HEADERS,然后在里面添加请求头信息即可。
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Mozilla/5.0'
}
1.2 方法二(随机请求头,添加到中间件)
- 首先在settings文件里边(添加在middlewares也可以)添加一个包含多个user-agent的列表(UA池)。
USER_AGENT_LIST = [
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
"Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; HUAWEI MT7-TL00 Build/HuaweiMT7-TL00) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
"Mozilla/5.0 (Linux; U; Android 4.1.1; zh-cn; HTC T528t Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30; 360browser(securitypay,securityinstalled); 360(android,uppayplugin); 360 Aphone Browser (2.0.4)"
]
- 在middlewares文件中导入settings里边建立的UA池(如果UA池建立在middlewares则不用导入)
- 新建一个类,重写process_request该函数即可。
from you_scrapy_project import settings
class UAMiddleware(object):
def process_request(self, request, spider):
ua = random.choice(settings.USER_AGENT_LIST) # 随机获取一个ua
request.headers['User-Agent'] = ua
- 最后别忘了去settings的downloadmiddlewares启动该中间件哦。
DOWNLOADER_MIDDLEWARES = {
'you_scrapy_project .middlewares.UAMiddleware': 400,
}
2.获取cookie
2.1 方法一(requests.requests.utils.dict_from_cookiejar)
import requests
url = 'https://www.baidu.com'
headers = {
'user-agent': 'Mozilla/5.0'
}
resp = requests.get(url, headers=headers)
# 将CookieJar转为字典:
cookie = requests.utils.dict_from_cookiejar(resp.cookies)
print(cookie) # {'BAIDUID': 'E1A1BC09CC5C0A5BE2AE7A315C55A6C1:FG=1', 'BIDUPSID': 'E1A1BC09CC5C0A5B6E1A2CEC568C2B06', 'PSTM': '1577864887', 'BD_NOT_HTTPS': '1'}
2.2 方法二(selenium的get_cookies())
from selenium import webdriver
url = 'https://www.baidu.com'
driver = webdriver.Chorme()
driver.get(url)
cookie = driver.get_cookies()
print(cookie) # 返回了一大堆数据, 如下
[{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '1468_21103_30210_30493_30284_26350_22160'}, {'domain': '.baidu.com', 'expiry': 1609401255.26318, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'E4B0685C3A0F2F823732B47A077C5010:FG=1'}, {'domain': '.baidu.com', 'expiry': 3725348902.263097, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'E4B0685C3A0F2F82CBE2EB17FB123491'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'}, {'domain': '.baidu.com', 'expiry': 3725348902.263128, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1577865255'}, {'domain': '.baidu.com', 'expiry': 1577951656.419035, 'httpOnly': False, 'name': 'BDORZ', 'path': '/', 'secure': False, 'value': 'B490B5EBF6F3CD402E515D22BCDA1598'}, {'domain': 'www.baidu.com', 'expiry': 1578729256, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '0'}]
scrapy的cookie只能用 dict 输入,所以需要将这一堆数据转换成字典。
cookie_list = {item['name']:item['value'] for item in cookie}
print(cookie_list) # {'H_PS_PSSID': '1468_21103_30210_30493_30284_26350_22160', 'BAIDUID': 'E4B0685C3A0F2F823732B47A077C5010:FG=1', 'BIDUPSID': 'E4B0685C3A0F2F82CBE2EB17FB123491', 'delPer': '0', 'PSTM': '1577865255', 'BDORZ': 'B490B5EBF6F3CD402E515D22BCDA1598', 'BD_UPN': '12314753', 'BD_HOME': '0'}
3. 为每一个请求添加cookie
3.1 方法一(直接在settings文件中添加)
- 直接添加到settings文件中即可。
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'Connection': 'keep-alive',
'Cookie': 'xxx',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',
}
3.2 方法二(添加到spider文件中)
- 如下,将cookie文件添加到spider文件,然后再请求中加上cookie文件即可。
import scrapy
class TransactionSpider(scrapy.Spider):
name = "you_spider"
allowed_domains = ['www.xxx.com']
cookie={
'Cookie': 'xxx'
}
def start_requests(self):
yield scrapy.Request(url=self.url, cookies=self.cookie, callback=self.parse)
3.3 方法三(添加到中间件)
- 首先在settings中设置,如下
#COOKIES_ENABLED = False # 取消注释,并将False更改为True
COOKIES_ENABLED = True
- 这里需要重写一个添加cookie的中间件
- 这里我处理后的以字典形式存在cookie存储到了redis数据库
import redis
# 登录中间件
class AddCookieMiddleware(object):
def __init__(self):
self.client = redis.StrictRedis() # '建立redis数据库的连接'
self.need_add_cookie = {
'you_spider_01',
'you_spider_02',
} # '看哪个spider需要添加cookie,就将它添加到这里'
def process_request(self, request, spider):
# '根据spider.name的名字去判断在不在self.need_add_cookie中,如果存在则添加cookie'
if spider.name in self.need_add_cookie :
cookie = self.client.get('cookies')
request.cookies = cookie
- 最后别忘了去settings的downloadmiddlewares启动该中间件哦。
DOWNLOADER_MIDDLEWARES = {
'you_scrapy_project.middlewares.AddCookieMiddleware': 501,
}
4. 多个spider运行
4.1 多个spider同时运行
略
4.2 多个spider顺序运行
在scrapy的启动项文件中,如下设置即可按顺序运行。
import os
os.system('scrapy crawl you_spider_01')
os.system('scrapy crawl you_spider_01')
5. Pipelines根据函数名决定走哪个管道
- 在spider中会导入items中的类
# spider.py
from you_scrapy_project.items import xxxpipeline # 需导入全路径
item = xxxpipeline()
item['date'] = xxx
item['name'] = xxx
item['id'] = xxx
yield item
- pipelines文件,重写一个管道
from you_scrapy_project.items import xxxpipeline # 需导入全路径
class XxxPipeline(object):
def process_item(self, item, spider):
if isinstance(item, xxx):
如果该函数名为xxx,则执行该操作
elif isinstance(item, ddd):
如果该函数名为ddd,则执行该操作
return item