scrapy总结
2018-11-02 本文已影响13人
叫我老村长
about-BY-gentle.jpg
自定义数据管道(注意激活管道)
可选方法
1.close_spider 爬虫结束的时候调用
2.open_spider 爬虫开启的时候调用
类方法
@classmethod
crawler ---> 包含了爬虫一些核心组件
可以获取setting 中的一些参数
图片下载
1,正常发起请求,获取图片二进制文件,保存。
2.自定义图片管道,继承ImagesPipeline
重写二方法
scrapy.Spider
customer_settings: ---> 覆盖全局setting
def start_requests():
根据起始url发起请求
def parse() ----> 回调函数
#实例
def start_requests(self):
# 使用场景:当你访问某个网站的时候,必须要登录之后,才可以获取数据
# 这时我们需要要重写start_requests,在这个方法里面模拟登录,获取
# coolies.
#模拟登录
通用爬虫
setting ---->
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 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
#反爬 --> 请求完,没有返回
}
爬虫文件
# allow:一般设置一个正则表达式,符合该正则表达式的连接,提取该url(常用)
# deny:同样是跟一个正则表达式,符合该正则表达式的连接,不提取该url
#(优先级比allow要高)
# allowed_domains:提取的连接,必须在allowed_domains设置的域下
# deny_domains: 提取链接时,一定不能提取deny_domains设置的域下
# restrict_xpaths:当提取链接的时候,我们可以使用xpath语法定位到某些标签,提取标签下,
# 符合规则的链接 (常用)
# tags:可以指定要提取哪些标签
# attrs:可以指定要提取标签的哪些属性
# restrict_css:当提取链接的时候,我们可以使用css语法定位到某些标签,提取标签下,
# 符合规则的链接 (常用)
# Rule(
# LinkExtractor(allow=('.*?qwd=&p=\d+',),
# deny=(),
# allowed_domains=(),
# deny_domains=(),
# restrict_xpaths=(),
# tags=(),
# attrs=(),
# restrict_css=(),
# ),
# callback='回调函数名称',
# follow=True | False, # 表示是否要跟进
# )
区别:
Spider类的设计原则是只爬取start_url列表中的网页,而CrawlSpider类定义了一些规则Rule来提供跟进链接的方便的机制,从爬取的网页结果中获取链接并继续爬取的工作.
注意:
注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider将会运行失败。
通常防止爬虫被反主要有以下几个策略:
DOWNLOAD_DELAY = 2
COOKIES_ENABLED = False
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 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
中间件
ip池,少量ip时:
```
import random
import base64
class RandomProxiesDownloadMiddlerware(object):
def __init__(self,proxies):
self.proxies = proxies
@classmethod
def from_crawler(cls,crawler):
proxies = crawler.settings['PROXIES']
return cls(proxies)
def process_request(self, request, spider):
dict_proxy = random.choice(self.proxies)
print(dict_proxy)
if dict_proxy['pwd_use'] is None:
#是一个不同代理
request.meta['proxy'] = dict_proxy['ip_port']
else:
#有账号密码的代理
# 1对账号密码进行base64编码
pwd_user = base64.b64encode(dict_proxy['pwd_use'].encode('utf8')).decode('utf8')
print(pwd_user)
#设置信令
request.headers['Proxy-Authorization'] = 'Basic' + ' ' + pwd_user
request.meta['proxy'] = dict_proxy['ip_port']
多个ip时,用数据库中的ip
#使用自定制的ip池
from middlerwareProject.xici import randomiphandler
class RandomProxiesDownloadMiddlerware(object):
def __init__(self):
self.handler = randomiphandler()
def process_request(self, request, spider):
#获取一个ip
proxy = self.handler.get_random_ip()
proxy_str = proxy['ip']+':'+proxy['port']
request.meta['proxy'] = proxy_str
设置ua,手动设置
class RandomUserAgentDownloadMiddlerware(object):
def __init__(self,useragents):
self.useragents = useragents
@classmethod
def from_crawler(cls,crawler):
userAgents = crawler.settings['USER_AGENTS']
return cls(userAgents)
def process_request(self,request,spider):
#随机获取一个ua
ua = random.choice(self.useragents)
request.headers['User-Agent'] = ua
#方式二
# request.headers.setdefault(b'User-Agent',ua)
使用fake_useragent第三方,随机获取ua
from fake_useragent import UserAgent
class RandomUserAgentDownloadMiddlerware(object):
def __init__(self):
self.useragent = UserAgent()
def process_request(self,request,spider):
#随机获取一个ua
random_ua = self.useragent.random
request.headers['User-Agent'] = ua
# 方式二
# request.headers.setdefault(b'User-Agent',ua)
cookies的设置:
class RandomCookiesDownloadMiddlerWare(object):
def __init__(self,cookies):
self.cookies = cookies
@classmethod
def from_crawler(cls,crawler):
cookies_list = crawler.settings['COOKIES']
return cls(cookies_list)
def process_request(self,request,spider):
random_cookies = random.choice(self.cookies)
# headers = {'Set-Cookie': cookies}
#设置随机的cookies
# request.headers['Set-Cookie'] = random_cookies
request.cookies = random_cookies
和selenium结合使用
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from scrapy.http import HtmlResponse
class SeleniumDownloadMiddlerWare(object):
def __init__(self):
self.driver = webdriver.Chrome(executable_path='/home/ljh/桌面/driver/chromedriver')
self.driver.set_page_load_timeout(20)
def __del__(self):
self.driver.quit()
def process_request(self,request,spider):
page_url = request.url
try:
self.driver.get(page_url)
if self.driver.page_source:
#url, status=200, headers=None, body=b'', flags=None, request=None
return HtmlResponse(url=page_url,status=200,headers='',body=self.driver.page_source.encode('utf8'),request=request)
except TimeoutException as err:
print('请求超时')
return HtmlResponse(url=page_url,status=500,headers='',body=b'',request=request)