爬虫

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)
上一篇 下一篇

猜你喜欢

热点阅读