微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python爬虫学习笔记-第二十三课(Scrapy框架进阶+Redis入门)

Scrapy框架进阶+Redis入门

1. 设置代理IP

1.1 基本概念

什么是代理IP:
代理IP服务器是在计算机上运行的专用计算机或软件系统,其充当端点设备(例如计算机)与用户或客户端从其请求服务的另一服务器之间的中介。

为什么要设置代理IP:

  1. 突破自身的IP访问限制,防止因短时间频繁访问导致IP被封;
  2. 隐藏自身真实的IP。

免费代理网站:

在这里插入图片描述

1.2 设置代理IP

import requests
url = 'httpbin.org/ip'
# 查看自身IP
res = requests.get(url)
print(res.text)
# 设置代理IP, 格式为IP:端口
proxy = {
    'http': '171.11.29.120:9999'
}
res = requests.get(url, proxies=proxy)
print(res.text)

PICTURE

这里结果并不是代码问题,免费的代理许多都不靠谱,大家都懂。

注意点:ipconfig显示的IP是内网私有的IP地址,该地址只适用于局域网,不能连通外网,而访问获取的IP是运营商分配的IP地址,可用于连接外网。

如何获取代理IP:

  1. 快代理、西刺代理… 免费的代理(几乎用不了);
  2. 付费代理。

豌豆代理每天可免费使用20个:https://h.wandouip.com/get#api

在这里插入图片描述

代理IP的匿名度:

  1. 透明:服务器知道了这次使用了代理,也知道真实的IP;
  2. 匿名:服务器知道了使用了代理,不知道真实的IP;
  3. 高匿:不知道使用了代理,也不知道真实的IP。

在下载中间件里面设置代理IP:

class IPProxyDownloaderMiddleware:
    PROXIES = [{"ip": "114.99.0.78", "port": 894, "expire_time": "2021-02-03 20:25:43"},
               {"ip": "114.99.0.78", "port": 894, "expire_time": "2021-02-03 20:25:43"}]

    def process_request(self, request, spider):
        proxy = random.choice(self.PROXIES)
        # 代理IP的格式:http://127.0.0.1:8889
        proxy_url = 'http://' + proxy['ip'] + ':' + str(proxy['port'])
        request.Meta['proxy'] = proxy_url
        return None

爬虫文件代码

import scrapy
class ProxyipSpider(scrapy.Spider):
    name = 'proxyip'
    allowed_domains = ['httpbin.org']
    start_urls = ['http://httpbin.org/ip']

    def parse(self, response):
        print(response.text)
        yield scrapy.Request(self.start_urls[0], dont_filter=True)

settings文件

BOT_NAME = 'SetProxyIP'

SPIDER_MODULES = ['SetProxyIP.spiders']
NEWSPIDER_MODULE = 'SetProxyIP.spiders'
LOG_LEVEL = 'WARNING'
ROBOTSTXT_OBEY = False
# 设置下载延迟
DOWNLOAD_DELAY = 1
# 打开下载中间件
DOWNLOADER_MIDDLEWARES = {
    # 'SetProxyIP.middlewares.SetproxyipDownloaderMiddleware': 543,
    'SetProxyIP.middlewares.IPProxyDownloaderMiddleware': 200
}

小总结
第一步:得有一个平台(网站)得给你提供有效的代理IP;
第二步:通过这个网站返回json数据 (ip、port、datatime);
第三步:在middleware里面创建一个中间件并书写相应的代码

2. scrapy集成selenium

2.1 代码需求

简书官网点击文章,如果文章专题里面有展开更多按钮,就点击相应的按钮,打印出文章对应的专题。
爬取链接https://www.jianshu.com/

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

2.2 案例代码

如何在scrapy中集成selenium ?
思路是先通过selenium正常的去操作,然后在把逻辑集成到scrapy当中。

from selenium import webdriver
from selenium.webdriver.support.ui import webdriverwait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
​
driver = webdriver.Chrome()
url = 'https://www.jianshu.com/p/7e2b63ed0292'
driver.get(url)
​
# 显示等待 等待 展开更多 这个按钮
webdriverwait(driver,6).until(
    EC.element_to_be_clickable((By.XPATH,'//section[position()=2]/div/div'))
)
​
while True:
    try:
        more_btn = driver.find_element_by_xpath('//section[position()=2]/div/div')
        # 无法用selenium正常点击按钮时用js的方法点击按钮
        driver.execute_script('arguments[0].click();',more_btn)
    except:
        break

运行结果:

星空梦想
康桥文苑
春梅书房琴谱
春梅书房共情篇
简书作家文学梦
悠云阁
诗词之界
会员征文超级权...
繁星集
现代诗刊
谈天说地
芳草集
记忆小站
想法
散文
哲思
简友广场

在这里插入图片描述

在scrapy中集成selenium时,将上述逻辑写到下载中间件中,让scrapy去访问每个文章
settings文件

BOT_NAME = 'JianShu'

SPIDER_MODULES = ['JianShu.spiders']
NEWSPIDER_MODULE = 'JianShu.spiders'
LOG_LEVEL='WARNING'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure a delay for requests for the same website (default: 0)
DOWNLOAD_DELAY = 1

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
}

# Enable or disable downloader middlewares
DOWNLOADER_MIDDLEWARES = {
   'JianShu.middlewares.JianshuDownloaderMiddleware': 543,
}

下载中间件的代码

from scrapy import signals
from selenium import webdriver
from selenium.webdriver.support.ui import webdriverwait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from scrapy.http.response.html import HtmlResponse

class JianshuDownloaderMiddleware:
  def __init__(self):
      self.driver = webdriver.Chrome()

  def process_request(self, request, spider):
      # 我们需要拦截 用selenium进行请求 把获取的数据封装成一个response对象
      self.driver.get(request.url)
      more_btn_xpath = '//div[@role="main"]/div[position()=1]/section[last()]/div[position()=1]/div[last()]'

      webdriverwait(self.driver, 100).until(
          EC.element_to_be_clickable((By.XPATH, more_btn_xpath))
      )

      while True:
          try:
              more_btn = self.driver.find_element_by_xpath(more_btn_xpath)
              self.driver.execute_script('arguments[0].click();', more_btn)
          except:
              break
      response = HtmlResponse(request.url, body=self.driver.page_source, request=request,
                              encoding='utf-8')
      return response

爬虫文件代码

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class Jsspider(CrawlSpider):
    name = 'js'
    allowed_domains = ['jianshu.com']
    start_urls = ['https://www.jianshu.com/p/8c3329505218']

    rules = (
        Rule(LinkExtractor(allow=r'.*/p/\w+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        pass

小总结:
我们要集成selenium,需要在下载中间件中去实现逻辑;
在下载中间件里需要返回一个response对象;
简书的标签做了处理,我们的解决方式是通过位置来进行标签的定位。

3. Scrapy框架进阶——Redis数据库

随着互联网+大数据时代的来临,传统的关系型数据库已经不能满足中大型网站日益增长的访问量和数据量。这个时候就需要一种能够快速存取数据的组件来缓解数据库服务I/O的压力,来解决系统性能上的瓶颈。

3.1 基本概念

MysqL数据库

  • 关系型数据库
  • 持久化数据,存储到硬盘;
  • 读取速度比较慢;
  • MysqL数据库的运行机制,存在大量的I/O操作。

Redis数据库

  • Nosql非关系数据库
  • 存储到缓存当中;
  • 读取速度比较快。
    小总结:Redis是⼀个高性能,开源的,C语言开发的,键值对存储数据的Nosql数据库

Nosqlsql数据库的比较:

  • 适用场景不同:sql数据库适合用于关系特别复杂的数据查询场景,nosql反之;
  • 事务:sql对事务的支持非常完善,而nosql基本不支持事务;
  • 两者在不断的取长补短。

Redis的特性:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用;
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供List,set等数据类型;
  • Redis支持数据的备份。

Redis的应用场景:
点赞/秒杀/直播平台的在线好友列表/商品排行榜

3.2 redis数据库的使用:

官网链接https://redis.io/
安装:在官网上下载后,解压直接放到想要的盘符里面。

基本的命令使用:
参考命令链接http://doc.redisfans.com/

在这里插入图片描述

DBSIZE 查看当前数据库的key数量
keys * 查看key的内容
FLUSHDB 清空当前数据库的key的数量
FLUSHALL 清空所有库的key(慎⽤)
exists key 判断key是否存在

简单示例:
启动服务:redis-server.exe

在这里插入图片描述


链接客户端:redis-cli.exe
查看key的内容keys *
清空所有库的key(慎用):FLUSHALL,可以不区分不大小写:

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐