Python scrapy增量爬取实例及实现过程解析

作者:boardMan 时间:2022-11-12 21:58:39 

这篇文章主要介绍了Python scrapy增量爬取实例及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

开始接触爬虫的时候还是初学Python的那会,用的还是request、bs4、pandas,再后面接触scrapy做个一两个爬虫,觉得还是框架好,可惜都没有记录都忘记了,现在做推荐系统需要爬取一定的文章,所以又把scrapy捡起来。趁着这次机会做一个记录。

目录如下:

  • 环境

  • 本地窗口调试命令

  • 工程目录

  • xpath选择器

  • 一个简单的增量爬虫示例

  • 配置介绍

环境

自己的环境下安装scrapy肯定用anaconda(再次强调anaconda的优越性

本地窗口调试与运行

开发的时候可以利用scrapy自带的调试功能进行模拟请求,这样request、response都会与后面代码保持一样。


# 测试请求某网站
scrapy shell URL
# 设置请求头
scrapy shell -s USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" URL

# 指定爬虫内容输出文件格式(json、csv等
scrapy crawl SPIDER_NAME -o FILE_NAME.csv

# 创建爬虫工程
scrapy startproject articles # 在当前目录创建一个scrapy工程

新工程结构介绍


# spiders文件下存放所有爬虫,item.py格式化数据输出
# middlewares.py 设置请求细节(请求头之类的),pipelines.py为数据输出的管道,每一个封装好的item都会经过这里
# settings.py 对工程进行全局设置(存放配置
├── articles
│  ├── articles
│  │  ├── __init__.py
│  │  ├── items.py
│  │  ├── middlewares.py
│  │  ├── pipelines.py
│  │  ├── settings.py
│  │  └── spiders
│  │    ├── healthy_living.py
│  │    ├── __init__.py
│  │    └── people_health.py
│  └── scrapy.cfg
├── README.en.md
└── README.md

页面解析神器——Xpath选择器

scrapy自带xpath选择器,很方便,简单介绍一些常用的


# 全站爬取神器--LinkExtractor,可以自动获取该标签下的所有url跟text(因为网站结构大都一个套路
from scrapy.linkextractors import LinkExtractor
le = LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1 clearFix']")# 返回一个迭代器,通过循环(for i in le),可获取url(i.url) (i.text)

# 获取属性class为所有aa的div标签内容中的内容
response.xpath("//div[@class='aa']/text()").extract()    # '//'代表获取所有,'/'代表获取第一个,类似的可以找属性为ul的其它标签

# 获取内容包含“下一页”的所有a标签中包含的链接(提取下一页链接神器
response.xpath("//a[contains(text(),'下一页')]/@href").extract()

一个简单的增量爬取示例

这里增量爬取的思想很简单:目标网站的数据都是按照时间排列的,所以在对某个连接进行request之前,先查询数据库中有没有这条数据,如果有,就停止爬虫,如果没有发起请求


class HealthyLiving(scrapy.Spider):
 # 一定要一个全局唯一的爬虫名称,命令行启动的时候需要指定该名称
 name = "healthy_living"
 # 指定爬虫入口,scrapy支持多入口,所以一定是lis形式
 start_urls = ['http://www.jkb.com.cn/healthyLiving/']

'''
 抓取大类标签入口
 '''
 def parse(self, response):
   le = LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1 clearFix']")
   for link in le.extract_links(response)[1:-1]:
     tag = link.text
     # 将这一级提取到的信息,通过请求头传递给下一级(这里是为了给数据打标签
     meta = {"tag": tag}
     # 依次解析每一个链接,并传递到下一级进行继续爬取
     yield scrapy.Request(link.url, callback=self.parse_articles, meta=meta)

'''
 抓取页面内的文章链接及下一页链接
 '''
 def parse_articles(self, response):
   # 接收上一级传递的信息
   meta = response.meta
   article_links = response.xpath("//div[@class='txt']/h4/a/@href").extract()
   for link in article_links:
     res = self.collection.find_one({"article_url": link}, {"article_url": 1})
     full_meta = dict(meta)
     # 将文章链接传入下一级
     full_meta.update({"article_url": link})
     if res is None:
       yield scrapy.Request(link, callback=self.parse_article, meta=full_meta)
     else:
       return
   next_page = response.xpath("//div[@class='page']//a[contains(text(),'»')]/@href").extract()[0]
   if next_page:
     yield scrapy.Request(next_page, callback=self.parse_articles, meta=meta)

# 最后解析页面,并输出
 def parse_article(self, response):
  # 从item.py中导入数据封装格式
   article_item = ArticlesItem()
   meta = response.meta
   # 利用xpath提取页面信息并封装成item
   try:
     article_item["tag"] = ""
     # ... 省略
   finally:
     yield article_item

工程配置介绍

设置请求头、配置数据库


# 设置请求头,在middlewares.py中设定,在settings.py中启用
class RandomUA(object):
 user_agents = [
     "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit"
     "/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
     "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
     "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit"
     "/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
   ]

def process_request(self, request, spider):
   request.headers["User-Agent"] = random.choice(self.user_agents)

# 设置数据入库处理,在pipeline.py进行配置,在settings.py进行启用
class MongoPipeline(object):
 def __init__(self, mongo_uri, mongo_db):
   self.mongo_uri = mongo_uri
   self.mongo_db = mongo_db

@classmethod
 def from_crawler(cls, crawler):
   return cls(
     mongo_uri=crawler.settings.get('MONGO_URI'),
     mongo_db=crawler.settings.get('MONGO_DB')
   )

def open_spider(self, spider):
   print("开始爬取", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
   self.client = pymongo.MongoClient(self.mongo_uri)
   self.db = self.client[self.mongo_db]

def process_item(self, item, spider):
   data = self.db[item.collection].find_one({"title": item["title"], "date": item["date"]})

if data is None:
     self.db[item.collection].insert(dict(item))
   # else:
   #   self.close_spider(self, spider)
   return item

def close_spider(self, spider):
   print("爬取结束", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
   self.client.close()
# 在settings.py启动:请求头的修改,数据库的配置
DOWNLOADER_MIDDLEWARES = {
 # 'articles.middlewares.ArticlesDownloaderMiddleware': 543,
 'articles.middlewares.RandomUA': 543,# 543代表优先级,数字越低优先级越高
}

ITEM_PIPELINES = {
 'articles.pipelines.MongoPipeline': 300,
}

# 一些其它配置
ROBOTSTXT_OBEY = True # 是否遵守网站的robot协议
FEED_EXPORT_ENCODING = 'utf-8' # 指定数据输出的编码格式
## 数据库配置
MONGO_URI = ''
MONGO_DB = ''
MONGO_PORT = 27017
MONGO_COLLECTION = ''

来源:https://www.cnblogs.com/CodeMLB/p/12088856.html

标签:Python,scrapy,增量,爬取
0
投稿

猜你喜欢

  • python和c语言哪个更适合初学者

    2022-06-22 08:23:29
  • 详解Python连接oracle的问题记录与解决

    2021-04-07 09:38:41
  • Javascript解决常见浏览器兼容问题的12种方法

    2024-04-10 10:47:43
  • PHP动态生成指定大小随机图片的方法

    2023-11-15 12:06:35
  • Python中extend和append的区别讲解

    2021-03-28 04:20:37
  • MySQL高级操作指令汇总

    2024-01-21 04:42:01
  • .Net行为型设计模式之迭代器模式(Iterator)

    2024-06-05 09:27:47
  • python3+PyQt5+Qt Designer实现扩展对话框

    2023-08-01 00:16:45
  • 用Python手把手教你实现2048小游戏

    2023-02-22 23:27:57
  • Oracle收购TimesTen 提高数据库软件性能

    2010-07-21 13:03:00
  • python多线程socket编程之多客户端接入

    2021-01-26 10:14:52
  • Python实现视频裁剪的示例代码

    2022-07-20 07:14:14
  • python自然语言编码转换模块codecs介绍

    2022-10-07 00:48:40
  • python爬虫数据保存到mongoDB的实例方法

    2021-10-10 09:52:24
  • 基于Python实现Excel转Markdown表格

    2021-04-27 17:05:04
  • Python实现的三层BP神经网络算法示例

    2021-05-16 19:21:05
  • 使用Python和百度语音识别生成视频字幕的实现

    2022-02-28 23:12:42
  • Python如何生成xml文件

    2022-07-25 06:00:33
  • MySQL是怎么保证主备一致的

    2024-01-21 13:13:42
  • python mysql断开重连的实现方法

    2024-01-24 01:20:26
  • asp之家 网络编程 m.aspxhome.com