zoukankan      html  css  js  c++  java
  • 自动给抽屉点赞、全站爬取cnblogs、scrapy的请求传参、提升scrapy爬取数据的效率、scrapy的中间件、selenium在scrapy中的使用流程、分布式爬虫(scrapy-redis)、破解知乎登陆(js逆向和解密)、爬虫的反扒措施

    ## 1 自动给抽屉点赞

    ```python

    from selenium import webdriver
    import time
    import requests

    bro=webdriver.Chrome(executable_path='./chromedriver.exe')
    bro.implicitly_wait(10)
    bro.get('https://dig.chouti.com/')

    login_b=bro.find_element_by_id('login_btn')
    print(login_b)
    login_b.click()

    username=bro.find_element_by_name('phone')
    username.send_keys('18953675221')
    password=bro.find_element_by_name('password')
    password.send_keys('lqz123')

    button=bro.find_element_by_css_selector('button.login-btn')
    button.click()
    # 可能有验证码,手动操作一下
    time.sleep(10)


    my_cookie=bro.get_cookies() # 列表
    print(my_cookie)
    bro.close()

    # 这个cookie不是一个字典,不能直接给requests使用,需要转一下
    cookie={}
    for item in my_cookie:
    cookie[item['name']]=item['value']


    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
    'Referer': 'https://dig.chouti.com/'}
    # ret = requests.get('https://dig.chouti.com/',headers=headers)
    # print(ret.text)


    ret=requests.get('https://dig.chouti.com/top/24hr?_=1596677637670',headers=headers)
    print(ret.json())
    ll=[]
    for item in ret.json()['data']:
    ll.append(item['id'])

    print(ll)
    for id in ll:
    ret=requests.post(' https://dig.chouti.com/link/vote',headers=headers,cookies=cookie,data={'linkId':id})
    print(ret.text)

    'https://dig.chouti.com/comments/create'
    '''
    content: 说的号
    linkId: 29829529
    parentId: 0

    '''
    ```



    ## 2 全站爬取cnblogs

    ```python
    # 详见代码
    ```



    ## 3 scrapy的请求传参

    ```python
    # 把要传递的数据放到meta中
    yield Request(urlmeta={'item':item})
    # 在response对象中取出来
    item=response.meta.get('item')
    ```



    ## 4 提升scrapy爬取数据的效率

    ```python
    - 在配置文件中进行相关的配置即可:(默认还有一套setting)
    #1 增加并发:
    默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。
    #2 降低日志级别:
    在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’
    # 3 禁止cookie:
    如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False
    # 4禁止重试:
    对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False
    # 5 减少下载超时:
    如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s
    ```



    ## 5 scrapy的中间件(下载中间件)

    ```python
    # 1 都写在middlewares.py
    # 2 爬虫中间件
    # 3 下载中间件
    # 4 要生效,一定要配置,配置文件


    # 下载中间件
    -process_request:返回不同的对象,后续处理不同(加代理...)
    # 1 更换请求头
    # print(type(request.headers))
    # print(request.headers)
    #
    # from scrapy.http.headers import Headers
    # request.headers['User-Agent']=''

    # 2 加cookie ---cookie池
    # 假设你你已经搭建好cookie 池了,
    # print('00000--',request.cookies)
    # request.cookies={'username':'asdfasdf'}

    # 3 加代理
    # print(request.meta)
    # request.meta['download_timeout'] = 20
    # request.meta["proxy"] = 'http://27.188.62.3:8060'
    -process_response:返回不同的对象,后续处理不同
    - process_exception
    def process_exception(self, request, exception, spider):
    print('xxxx')
    # 不允许直接改url
    # request.url='https://www.baidu.com'
    from scrapy import Request
    request=Request(url='https://www.baidu.com',callback=spider.parser)
    return request


    ```



    ## 6 selenium在scrapy中的使用流程

    ```python
    # 当前爬虫用的selenium是同一个

    # 1 在爬虫中初始化webdriver对象
    from selenium import webdriver
    class CnblogSpider(scrapy.Spider):
    name = 'cnblog'
    ...
    bro=webdriver.Chrome(executable_path='../chromedriver.exe')
    # 2 在中间件中使用(process_request)
    spider.bro.get('https://dig.chouti.com/') response=HtmlResponse(url='https://dig.chouti.com/',body=spider.bro.page_source.encode('utf-8'),request=request)
    return response

    # 3 在爬虫中关闭
    def close(self, reason):
    print("我结束了")
    self.bro.close()
    ```



    ## 7 去重规则源码分析

    ```python
    # 详见代码
    ```



    ## 8 分布式爬虫(scrapy-redis)

    ```python
    # 1 pip3 install scrapy-redis
    # 2 原来继承Spider,现在继承RedisSpider
    # 3 不能写start_urls = ['https:/www.cnblogs.com/']
    # 4 需要写redis_key = 'myspider:start_urls'
    # 5 setting中配置:

    # redis的连接
    REDIS_HOST = 'localhost' # 主机名
    REDIS_PORT = 6379 # 端口
    # 使用scrapy-redis的去重
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 使用scrapy-redis的Scheduler
    # 分布式爬虫的配置
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 持久化的可以配置,也可以不配置
    ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 299
    }


    # 9现在要让爬虫运行起来,需要去redis中以myspider:start_urls为key,插入一个起始地址lpush myspider:start_urls https://www.cnblogs.com/
    ```



    ## 9 破解知乎登陆(js逆向和解密)

    ```python
    client_id=c3cef7c66a1843f8b3a9e6a1e3160e20&
    grant_type=password&
    timestamp=1596702006088&
    source=com.zhihu.web&
    signature=eac4a6c461f9edf86ef33ef950c7b6aa426dbb39&
    username=%2B86liuqingzheng&
    password=1111111&
    captcha=&
    lang=en&
    utm_source=&
    ref_source=other_https%3A%2F%2Fwww.zhihu.com%2Fsignin%3Fnext%3D%252F"


    # 破解知乎登陆

    import requests #请求解析库

    import base64 #base64解密加密库
    from PIL import Image #图片处理库
    import hmac #加密库
    from hashlib import sha1 #加密库
    import time
    from urllib.parse import urlencode #url编码库
    import execjs #python调用node.js
    from http import cookiejar as cookielib
    class Spider():
    def __init__(self):
    self.session = requests.session()
    self.session.cookies = cookielib.LWPCookieJar() #使cookie可以调用save和load方法
    self.login_page_url = 'https://www.zhihu.com/signin?next=%2F'
    self.login_api = 'https://www.zhihu.com/api/v3/oauth/sign_in'
    self.captcha_api = 'https://www.zhihu.com/api/v3/oauth/captcha?lang=en'
    self.headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
    }

    self.captcha ='' #存验证码
    self.signature = '' #存签名

    # 首次请求获取cookie
    def get_base_cookie(self):
    self.session.get(url=self.login_page_url, headers=self.headers)

    def deal_captcha(self):
    r = self.session.get(url=self.captcha_api, headers=self.headers)
    r = r.json()
    if r.get('show_captcha'):
    while True:
    r = self.session.put(url=self.captcha_api, headers=self.headers)
    img_base64 = r.json().get('img_base64')
    with open('captcha.png', 'wb') as f:
    f.write(base64.b64decode(img_base64))
    captcha_img = Image.open('captcha.png')
    captcha_img.show()
    self.captcha = input('输入验证码:')
    r = self.session.post(url=self.captcha_api, data={'input_text': self.captcha},
    headers=self.headers)
    if r.json().get('success'):
    break

    def get_signature(self):
    # 生成加密签名
    a = hmac.new(b'd1b964811afb40118a12068ff74a12f4', digestmod=sha1)
    a.update(b'password')
    a.update(b'c3cef7c66a1843f8b3a9e6a1e3160e20')
    a.update(b'com.zhihu.web')
    a.update(str(int(time.time() * 1000)).encode('utf-8'))
    self.signature = a.hexdigest()

    def post_login_data(self):
    data = {
    'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
    'grant_type': 'password',
    'timestamp': str(int(time.time() * 1000)),
    'source': 'com.zhihu.web',
    'signature': self.signature,
    'username': '+8618953675221',
    'password': '',
    'captcha': self.captcha,
    'lang': 'en',
    'utm_source': '',
    'ref_source': 'other_https://www.zhihu.com/signin?next=%2F',
    }

    headers = {
    'x-zse-83': '3_2.0',
    'content-type': 'application/x-www-form-urlencoded',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
    }

    data = urlencode(data)
    with open('zhih.js', 'rt', encoding='utf-8') as f:
    js = execjs.compile(f.read(), cwd='node_modules')
    data = js.call('b', data)

    r = self.session.post(url=self.login_api, headers=headers, data=data)
    print(r.text)
    if r.status_code == 201:
    self.session.cookies.save('mycookie')
    print('登录成功')
    else:
    print('登录失败')

    def login(self):
    self.get_base_cookie()
    self.deal_captcha()
    self.get_signature()
    self.post_login_data()
    if __name__ == '__main__':
    zhihu_spider = Spider()
    zhihu_spider.login()


    ```

    ## 10 爬虫的反扒措施

    ```python
    1 user-agent
    2 referer
    3 cookie(cookie池,先访问一次)
    4 频率限制(代理池,延迟)
    5 js加密(扣出来,exjs模块指向)
    6 css加密
    7 验证码(打码平台),半手动
    8 图片懒加载
    ```



    # 拓展

    ```python
    热更新:不停机更新

    https://www.cnblogs.com/deali/p/13372922.html
    ```
  • 相关阅读:
    Servlet与JSP转发与包含---forwardinclude
    爬虫---正则表达式
    MapReduce的核心资料索引
    设计模式之单例模式Singleton pattern
    HTTP会话的使用与管理
    (二)jquery学习----jquery的效果
    (一)jquery学习
    webStorm2017 安装及使用
    linux下的符号链接和硬链接
    <初级程序员> git 的初级使用
  • 原文地址:https://www.cnblogs.com/0B0S/p/13618669.html
Copyright © 2011-2022 走看看