scrapy的使用
scrapy架构和目录介绍
# pip3 install scrapy # 创建项目:scrapy startproject cnblogs_spider 等同于django创建项目 # 创建爬虫:scrapy genspider cnblogs www.cnblogs.com 等同于创建app -本质就是在spiders文件夹下创建一个py文件,写入一些代码 # 运行爬虫:scrapy crawl 爬虫名
项目目录介绍
cnblogs_spider # 项目名字 -cnblogs_spider # 文件夹 -spiders # 文件夹,下面放了一个个爬虫文件 -cnblogs.py # 一个个的爬虫文件 items.py # 模型类写了一些字段---》类似于django的models middlewares.py # 中间件:爬虫中间件和下载中间件 pipelines.py # 管道:存储数据的代码写在这 settings.py # 项目的配置文件 scrapy.cfg # 项目上线需要用到,不用管 # 重点:咱们以后主要是在cnblogs.py爬虫文件中写爬取和解析的逻辑,pipelines写存储
scrapy架构
# 引擎(EGINE)-->大总管,负责全部的数据流向--》内置的,咱们不需要写 引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。 # 调度器(SCHEDULER)---》对要爬取的地址进行排队,去重 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址 # 下载器(DOWLOADER)--》真正负责下载---》高效的异步模型 用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的 # 爬虫(SPIDERS)--》咱们重点写的地方,解析响应,从响应中提取要保存的数据和下一次爬取的地址 SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求 # 项目管道(ITEM PIPLINES)---》存储数据的逻辑---》可以存到文件,redis,mysql。。。 在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作 # 下载器中间件(Downloader Middlewares)--》用的多 位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request(加请求头,加cookie,加代理),已经从DOWNLOADER传到EGINE的响应response进行一些处理 # 爬虫中间件(Spider Middlewares)---》用的少 位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)
py文件直接运行爬虫
# 右键运行它就可以运行爬虫,不需要每次都敲命令 from scrapy import cmdline # cmdline.execute(['scrapy', 'crawl' ,'cnblogs','--nolog']) cmdline.execute(['scrapy', 'crawl' ,'cnblogs'])
scrapy解析数据
################################### 重点 1 response对象有css方法和xpath方法 -css中写css选择器 -xpath中写xpath选择 2 重点1: -xpath取文本内容 './/a[contains(@class,"link-title")]/text()' -xpath取属性 './/a[contains(@class,"link-title")]/@href' -css取文本 'a.link-title::text' -css取属性 'img.image-scale::attr(src)' 3 重点2: .extract_first() 取一个 .extract() 取所有
setting相关配置
# 两套配置,内置一套,用户一套 ROBOTSTXT_OBEY = False # 是否遵循爬虫协议,如果写了它,一般网站都不让爬,基本写成false USER_AGENT = '浏览器头' # 爬虫请求头中USER_AGENT是什么,做成浏览器的样子 LOG_LEVEL='ERROR' # 日志级别改成ERROR,以后错误日志会打印,普通日志不打印 #---------#####------- SPIDER_MIDDLEWARES=[] # 爬虫中间件,可以写多个 DOWNLOADER_MIDDLEWARES=[] # 下载中间件类,配置在这,可以配多个 ITEM_PIPELINES=[] # 保存数据,会执行到的类,类内部写保存逻辑
提高爬虫效率配置
#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
全站爬取cnblogs文章
import scrapy from cnblogs_spider.items import CnblogsSpiderItem from scrapy.http import Request class CnblogsSpider(scrapy.Spider): name = 'cnblogs' allowed_domains = ['www.cnblogs.com'] start_urls = ['http://www.cnblogs.com/'] def parse(self, response): res = response.text article_list = response.xpath('//*[@id="post_list"]/article[@class="post-item"]') for article in article_list: item = CnblogsSpiderItem() title = article.xpath('./section/div/a/text()').extract_first() descriptive = article.xpath('./section/div/p/text()').extract()[0].replace('\n', '').replace(' ', '') if not descriptive: descriptive = article.xpath('./section/div/p/text()').extract()[1].replace('\n', '').replace(' ', '') img = article.xpath('./section/div/p/a/img/@src').extract_first() name = article.xpath('./section/footer/a/span/text()').extract_first() detail_url = article.xpath('./section/div/a/@href').extract_first() item['title'] = title # 不能使用 . 赋值,必须用 [] 赋值 item['descriptive'] = descriptive # 不能使用 . 赋值,必须用 [] 赋值 item['name'] = name # 不能使用 . 赋值,必须用 [] 赋值 item['img'] = img # 不能使用 . 赋值,必须用 [] 赋值 yield Request(url=detail_url, callback=self.parse_detail, meta={'item': item}) # 爬取文章列表页的下一页 next_url = 'https://www.cnblogs.com' + response.xpath( '//*[@id="paging_block"]/div/a[last()]/@href').extract_first() # next_url='https://www.cnblogs.com'+response.css('#paging_block > div > a:last-child::attr(href)').extract_first() print(next_url) # 继续爬取下一页,再爬完,解析方式还是这个解析方式 yield Request(url=next_url) def parse_detail(self, response): # 解析出文章详情--》如何对上之前的文章标题,摘要。。。 item = response.meta.get('item') detail = str(response.css('#cnblogs_post_body').extract_first()) item['detail'] = detail yield item # 触发pipline,走存储
item.py
# Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class CnblogsSpiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() img = scrapy.Field() name = scrapy.Field() descriptive = scrapy.Field() detail_url = scrapy.Field() detail = scrapy.Field()
pipelines.py
# Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html # useful for handling different item types with a single interface from itemadapter import ItemAdapter import pymysql class CnblogsSpiderPipeline: # 所有的保存都用一个连接,最后存完把连接关闭,爬虫一启动打开数据库连接,爬虫关闭,关闭数据库连接 def open_spider(self,spider): print("我开了") self.conn = pymysql.connect( user='root', password="456", host='127.0.0.1', database='cnblogs', port=3306, autocommit=True # 自动提交 ) self.cursor = self.conn.cursor() def process_item(self, item, spider): # 每个文章都会一次次的触发该方法的执行,在这里写保存逻辑 print('pipline:', item['title']) self.cursor.execute('insert into article (title,descriptive,detail,name,img) values (%s,%s,%s,%s,%s)', args=[item['title'], item['descriptive'], item['detail'], item['name'], item['img'], ]) return item def close_spider(self,spider): print('我关了') self.cursor.close() self.conn.close()
加代理,加header,集成selenium
0 在下载中间件的process_reqeust方法中 1 加cookie # request.cookies['name']='lqz' # request.cookies= {} 2 修改header # request.headers['Auth']='asdfasdfasdfasdf' # request.headers['USER-AGENT']='ssss' 3 加代理 request.meta['proxy']='http://103.130.172.34:8080' 4 fake_useragent模块,可以随机生成user-aget from fake_useragent import UserAgent ua = UserAgent() print(ua.ie) #随机打印ie浏览器任意版本 print(ua.firefox) #随机打印firefox浏览器任意版本 print(ua.chrome) #随机打印chrome浏览器任意版本 print(ua.random) #随机打印任意厂家的浏览器
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)