当前位置: 首页 > news >正文

有模板怎么做网站合肥网站建设黄页

有模板怎么做网站,合肥网站建设黄页,专业制作ppt,河南建设网站公司Scrapy框架基础Scrapy框架进阶 【五】持久化存储 命令行#xff1a;json、csv等管道#xff1a;什么数据类型都可以 【1】命令行简单存储 #xff08;1#xff09;语法 Json格式 scrapy crawl 自定义爬虫程序文件名 -o 文件名.jsonCSV格式 scrapy crawl 自定义爬虫程… Scrapy框架基础Scrapy框架进阶 【五】持久化存储 命令行json、csv等管道什么数据类型都可以 【1】命令行简单存储 1语法 Json格式 scrapy crawl 自定义爬虫程序文件名 -o 文件名.jsonCSV格式 scrapy crawl 自定义爬虫程序文件名 -o 文件名.csv -t csv2示例 重点是parse函数需要返回保存的数据 # 假设从浏览器拿到了想保存的数据文件 def parse(self, response):items []for i in range(5):item[fname{i}] fvalue{i}items.append(item)return items 保存为json格式文件 scrapy crawl test -o output.json# output.json [ {name0: value{0}}, {name1: value{1}}, {name2: value{2}}, {name3: value{3}}, {name4: value{4}} ]【2】管道存储 保存在数据库mysql中保存在本地txt文件中 1第一步从前端处理数据并返回 这里假设数据是从response中分析出来的注意item要放在循环中注意item要放在循环中注意item要放在循环中 import scrapy from ..items import ScrapyTestItemclass TestSpider(scrapy.Spider):name testallowed_domains [www.test.com]start_urls [https://www.test.com/]def parse(self, response):for i in range(5):item ScrapyTestItem()item[name] fbruce{i}item[avatar] favatar img src{i}item[introduce] flong long introduce{i}yield item2第一步创建管道数据模型 需要在items.py文件中创建一个类 类似于Django的模型表这个简单无论是什么类型字段都是scrapy.Field() import scrapy class ScrapyTestItem(scrapy.Item):name scrapy.Field()avatar scrapy.Field()introduce scrapy.Field()3第二步定义管道数据处理类 在Scrapy中parse 方法返回的数据无论是Item对象还是其他数据结构会被Scrapy引擎自动迭代、自动迭代、自动迭代并逐个传递给Pipeline的process_item方法。 需要在pipline.py文件中创建一个类 open_spider(self, spider) 当爬虫开始时这里会执行一些初始化操作例如可以建立数据库连接、打开文件等spider参数不能少 close_spider(self, spider) 当爬虫结束时这里会执行一些清理操作例如可以关闭数据库连接、关闭文件等spider参数不能少 process_item 每次要保存一个对象时这个方法会被触发在这里可以对item进行进一步的处理然后保存到数据库或者文件等 创建数据库和表 create database scrapyCREATE TABLE test (id int(11) NOT NULL AUTO_INCREMENT,name varchar(50) DEFAULT NULL,avatar varchar(255) DEFAULT NULL,introduce text,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; 创建数据库处理类 import pymysqlclass ScrapyTestMysqlPipeline:def open_spider(self, spider):self.conn pymysql.connect(userroot,password000,host127.0.0.1,port 3306,databasescrapy,cursorclasspymysql.cursors.DictCursor,)self.cursor self.conn.cursor()def close(self, spider):# 关闭句柄self.cursor.close()# 关闭数据库链接self.conn.close()def process_item(self, item, spider):sql_str insert INTOtest(name, avatar, introduce)values(%s, %s, %s);self.cursor.execute(sql_str, args(item.get(name),item.get(avatar),item.get(introduce),))self.conn.commit()return item创建本地文件保存类 class ScrapyTestTxtPipeline:def open_spider(self, spider):self.fp open(output.txt, wt, encodingutf8)def close_spider(self, spider):self.fp.close()def process_item(self, item, spider):# 已经自动迭代self.fp.write(str(item) \n)return item4第四步配置文件中注册管道类 Pipline的执行顺序会按照ITEM_PIPELINES字典中的定义顺序执行 数字越小优先级越高执行顺序越靠前建议数字范围0-1000没有强制规定 ITEM_PIPELINES {scrapy_test.pipelines.ScrapyTestMysqlPipeline: 100,scrapy_test.pipelines.ScrapyTestJsonPipeline: 300, }5最后启动项目 命令行 scrapy crawl testpy文件 from scrapy.cmdline import execute execute([scrapy, crawl, test])【六】中间件 【1】爬虫中间件 # 爬虫中间件 class Day06StartSpiderMiddleware:classmethoddef from_crawler(cls, crawler):# 这是一个类方法Scrapy使用它来创建爬虫中间件实例。# 这个方法通常用于连接中间件到Scrapy的信号。# 在这个例子中它将spider_opened方法连接到spider_opened信号。s cls()crawler.signals.connect(s.spider_opened, signalsignals.spider_opened)return sdef process_spider_input(self, response, spider):# 这个方法在每次响应通过爬虫中间件并进入爬虫时被调用。# 它允许修改响应或执行其他操作。# 如果不想修改响应可以返回None# 如果想阻止响应继续传递给爬虫可以抛出一个异常。return Nonedef process_spider_output(self, response, result, spider):# 这个方法在爬虫处理完响应并返回结果后被调用。# 它允许处理或修改爬虫的输出。# 必须返回一个包含请求或项目对象的可迭代对象。# 在这个例子中它只是简单地返回了原始结果。for i in result:yield idef process_spider_exception(self, response, exception, spider):# 当爬虫或其他爬虫中间件中的process_spider_input方法抛出异常时这个方法会被调用。# 它允许处理异常例如记录错误或生成新的请求。# 可以返回None或包含请求或项目对象的可迭代对象。# 在这个例子中这个方法没有做任何事情。passdef process_start_requests(self, start_requests, spider):# 这个方法在爬虫的起始请求被发送之前被调用。# 它与process_spider_output方法类似# 但不同之处在于它不与特定的响应相关联。# 必须只返回请求而不是项目。# 在这个例子中它只是简单地返回了原始的起始请求。# Must return only requests (not items).for r in start_requests:yield rdef spider_opened(self, spider):# 这是一个当爬虫被打开时由Scrapy信号触发的方法。# 在这个例子中它使用爬虫的日志记录器记录一条信息说明哪个爬虫被打开了。spider.logger.info(Spider opened: %s % spider.name) 【2】下载中间件 class ScrapyTestDownloaderMiddleware:# Not all methods need to be defined. If a method is not defined,# scrapy acts as if the downloader middleware does not modify the# passed objects.classmethoddef from_crawler(cls, crawler):# 这个类方法由Scrapy调用用于创建下载器中间件实例。# 在这个方法中可以连接中间件到Scrapy的信号# 例如连接spider_opened信号到spider_opened方法。s cls()crawler.signals.connect(s.spider_opened, signalsignals.spider_opened)return sdef process_request(self, request, spider):# 当每个请求通过下载器中间件时这个方法会被调用。# 可以在这个方法中修改请求或者返回一个新的请求或响应对象。# 如果返回None则请求会继续被处理。# 如果返回Request对象Scrapy会停止处理当前的请求并开始处理新的请求。# 如果返回Response对象Scrapy将不会发送请求而是直接将该响应传递给process_response方法。# 如果抛出IgnoreRequest异常Scrapy将不会发送请求并且会调用所有已安装的下载器中间件的process_exception方法。f# installed downloader middleware will be calledreturn Nonedef process_response(self, request, response, spider):# 当下载器返回响应时这个方法会被调用。# 可以在这里修改响应或者返回一个新的请求或响应对象。# 如果返回Response对象该响应将被传递给爬虫。# 如果返回Request对象Scrapy将停止处理当前的响应并开始处理新的请求。# 如果抛出IgnoreRequest异常Scrapy将不会将响应传递给爬虫并且会调用所有已安装的下载器中间件的process_exception方法。return responsedef process_exception(self, request, exception, spider):# 当下载处理器或process_request方法来自其他下载器中间件抛出异常时这个方法会被调用。# 可以在这里处理异常例如记录错误、返回一个新的请求或响应对象或者简单地忽略异常。# 如果返回None异常会继续被处理。# 如果返回Response或Request对象Scrapy将停止处理当前的异常并继续处理返回的响应或请求。passdef spider_opened(self, spider):# 当爬虫被打开时这个方法会被Scrapy的信号机制调用。# 可以在这里执行一些初始化的工作或者记录关于哪个爬虫被打开的信息。spider.logger.info(Spider opened: %s % spider.name) 【3】配置文件中注册 SPIDER_MIDDLEWARES {scrapy_test.middlewares.ScrapyTestSpiderMiddleware: 543, }DOWNLOADER_MIDDLEWARES {scrapy_test.middlewares.ScrapyTestDownloaderMiddleware: 543, }【4】下载中间件案例–修改请求头 class ScrapyTestDownloaderMiddleware:# 从代理池中获取可用代理staticmethoddef get_proxy(flag):if flag:res requests.get(http://代理池地址/get/?typehttps).json()return https:// res.get(proxy)else:res requests.get(http://代理池地址/get/).json()return http:// res.get(proxy)def process_request(self, request, spider):# 自定义代理根据request.url判断是https还是httpflag https in request.urlproxy_url self.get_proxy(flag)if proxy_url:request.meta[proxy] proxy_urlprint(fUsing proxy: {proxy_url})# 添加指定cookierequest.cookies[name] value# 或cookies字符串request.headers[Cookie] namevalue; anothernameanothervalue# 添加源页面地址request.headers[referer] https://example.com# 添加随机UA验证from fake_useragent import UserAgentrequest.headers[User-Agent] str(UserAgent().random)return Nonedef process_exception(self, request, exception, spider):# 处理由于代理问题引发的异常print(f下载中间异常: {exception})# 这里可以添加逻辑来重试请求或更换代理return None【八】CrawlSpider 【1】介绍 1简介 CrawlSpider是Spider的一个派生类它继承自Spider类并在此基础上增加了新的属性和方法。这意味着CrawlSpider拥有Spider的所有功能和特性并具备一些额外的独特功能。 2作用 自动跟踪链接 CrawlSpider能够自动解析页面中的链接并根据设定的规则跳转到其他页面以便爬取整个网站的所有页面。这使得CrawlSpider在处理大型网站或需要深度爬取的场景时非常有效。 数据提取规则 CrawlSpider提供了一种方便的方式来定义如何从页面中提取数据。通过使用基于XPath或CSS选择器的规则用户可以轻松地提取所需的目标数据。 避免重复爬取 CrawlSpider会自动管理已经爬取过的链接从而避免在爬取过程中重复访问同一个页面。这有助于减少不必要的网络请求和提高爬取效率。 3特别之处 规则定义 CrawlSpider通过其特有的属性“rules”来定义爬取规则。这些规则包括链接提取器LinkExtractor和回调函数callback它们共同决定了如何提取和处理页面上的链接。这使得CrawlSpider在处理具有特定结构和链接模式的网站时更加灵活和高效。 链接提取器 CrawlSpider中的链接提取器LinkExtractor是其特别之处之一。这个提取器可以自动从页面中识别并提取出符合特定模式的链接从而极大地简化了链接提取的过程。这使得CrawlSpider在处理大型、复杂的网站时具有更高的效率和准确性。 【2】使用 方法名不建议使用parse用其他名字 1创建CrawlSpider 和普通的spider差不多 这里指定使用crawl基础模板 scrapy genspider -t crawl 自定义爬虫程序文件名 目标地址2使用自定义规则 Rule(LinkExtractor(allowr地址正则表达式), callback回调函数, followFalse) LinkExtractor用于从响应中(response)中自动根据allow的正则表达式提取链接callback回调函数的字符串follow是否从匹配到的链接继续递归提取链接即只是爬取一页中可以看到的链接还是继续递归爬取 可以使用多条规则rules是个元组或者列表 rules (# 多页资源匹配提取分页链接但不跟进 Rule(LinkExtractor(allowrhttps://www.example.com/p/\d), callbackparse_page, followFalse),# 详情页面链接匹配提取详情链接也不跟进Rule(LinkExtractor(allowrhttps://www.example.com/\w/p/\d), callbackparse_detail, followFalse), )3多页数据方法传递 yield scrapy.Request(urldetail_url, callbackself.detail_parse, meta{item: item}) 这个是将详情页的url地址携带数据meta发送给callback回调函数url要爬取的网页内容callback处理爬取url的响应meta在请求的生命周期中传递数据 import scrapy class MySpider(CrawlSpider): name test allowed_domains [www.example.com]start_urls [https://example.com] rules [Rule(LinkExtractor(allowrhttps://www.example.com/sitehome/p/\d), callbackparse_page, followFalse),]def parse_page(self, response): # 获得每个需要的divdiv_list response.xpath()for div in div_list: # 假设有一个item对象用于存储数据 item MyItem() # 保存这里获得的数据item[title] div.xpath().extract()[0]... # 获得详情页地址detail_url div.xpath(/herf).extract()[0]# 生成Request对象并传递item通过meta yield scrapy.Request(urldetail_url, callbackself.parse_detail, meta{item: item}) def parse_detail(self, response): # 从meta中获取之前传递的item对象 item response.meta[item] # 从响应中继续提取信息item[detail] response.xpath(h1::text).extract_first() ...# 返回item准备交给pipeline处理 yield item【九】集成selenium 【1】介绍 scrapy默认使用的是requests模块发送请求 无法执行js 所以需要使用selenium模块根据scrapy框架可知 需要修改下载中间件的入口将需要特殊处理的地址发送给selenium 【2】使用方法 假设 正常请求通过scrapy默认requests获取详情页面需要使用selenium获取 如何区分不同的请求 根据不同的地址参数判断是否使用selenium根据request.meta[‘is_selenium’]给定的参数进行判断 添加参数yield Request(urlurl, callbackself.detail_parse, meta{item: item,is_selenium:True})获取参数request.meta.get(is_selenium) 1添加自定义的selenium中间件 from scrapy import signalsclass SeleniumMiddleWare:def __init__(self):from selenium import webdriverfrom selenium.webdriver.edge.service import Servicebrowser_path os.path.join(os.path.dirname(os.path.dirname(__file__)), msedgedriver.exe)self.browser webdriver.Edge(serviceService(browser_path), optionsself.make_options())self.browser.implicitly_wait(10)classmethoddef from_crawler(cls, crawler):s cls()crawler.signals.connect(s.spider_opened, signalsignals.spider_opened)crawler.signals.connect(s.spider_closed, signalsignals.spider_closed)return sstaticmethoddef make_options():from selenium.webdriver.edge.options import Optionsoptions Options()options.add_argument(window-size1920x1080)# options.add_argument(--headless)options.add_argument(--disable-gpu)options.add_experimental_option(excludeSwitches, [enable-automation])options.add_experimental_option(useAutomationExtension, False)return optionsdef spider_opened(self, spider):spider.logger.info(Browser Opened)# 将浏览器实例绑定到spider上方便process_request使用spider.browser self.browserdef spider_closed(self, spider):spider.logger.info(Browser Closed)spider.browser.quit()def process_request(self, request, spider):# 根据标志判断是否使用selenium# if request.meta.get(is_selenium):# 根据地址区分是否使用seleniumif article not in request.url:spider.logger.info(fUsing Selenium for Url: {request.url})spider.browser.get(request.url)from scrapy.http.response.html import HtmlResponseresponse HtmlResponse(urlrequest.url, bodybytes(spider.browser.page_source, encodingutf8)) # 编码可能要调整return response# 使用scrapy默认处理请求return None2注册中间件 在配置文件settings中 DOWNLOADER_MIDDLEWARES {scrapy_test.middlewares.SeleniumMiddleWare: 555, }【十】去重过滤器 在scrapy框架中 为了确保爬取到的数据是唯一的避免重复爬取相同的页面或数据 scrapy默认使用了基于Request指纹的去重机制除了默认的去重规则scrapy还支持自定义去重规则 【1】基于Request指纹的去重 1去重核心代码 位置 from scrapy.core.scheduler import Schedulerdef enqueue_request(self, request: Request) - bool:def request_seen(self, request: Request) - bool:class RFPDupeFilter(BaseDupeFilter):def request_seen(self, request: Request) - bool: self.fingerprints: Set[str] set()def request_fingerprint(self, request: Request) - str:return self.fingerprinter.fingerprint(request).hex() def request_seen(self, request: Request) - bool:fp self.request_fingerprint(request)if fp in self.fingerprints:return Trueself.fingerprints.add(fp)if self.file:self.file.write(fp \n)return False讲解 在类中定义了一个实例变量fingerprints 是一个集合集合具有去重的功能用于存储已经发送过的request指纹 在类中定义了一个方法request_fingerprint 使用fingerprinter对象的fingerprint方法对request进行计算计算指纹并将指纹转换为十六进制的字符串 在类中定义了方法request_seen 首先计算request的指纹判断指纹是否在访问过的集合中 为真那么久说明是已经访问过 添加这个请求的指纹到指纹集合中检查self.file是否存在打开的文件句柄用于持久化存储指纹 存在就将指纹写入这个文件并换行最终返回False说明是一个新的request 2测试指纹 我们对两个相同请求结果但是不同url进行测试 例如 https://www.example.com?keys154623valueqbzhttps://www.example.com?valueqbzkeys154623这两个的地址虽然不同传递给后端的结果却相同 所以这两个的指纹应该是一样的 示例 from scrapy.utils.request import RequestFingerprinter from scrapy import Requestfinger_printer RequestFingerprinter() request1 Request(urlhttps://www.example.com?valueqbzkeys154623) request2 Request(urlhttps://www.example.com?keys154623valueqbz)res1 finger_printer.fingerprint(request1).hex() res2 finger_printer.fingerprint(request2).hex() print(res2 res1) # True【2】自定义过滤器 1布隆过滤器Bloom Filter 优点 空间效率高 使用位数组存储信息比传统的哈希表或集合数据结构更小 时间效率高 查找元素通过几次简单的位运算 适用于大规模数据 高空间和时间效率所以适用于处理大规模数据 支持集合运算 支持并集、交集等集合运算这使得它在某些场景下非常有用 具有一定容错能力 布隆过滤器是概率型数据结构即存在哈希冲突但误报率可以通过调整参数进行控制 原理 布隆过滤器主要由一个位数组和k个哈希函数组成。当需要插入一个元素时该元素会被k个哈希函数映射到位数组的k个不同位置并将这些位置上的位设置为1。当需要查询一个元素是否存在于集合中时同样使用这k个哈希函数找到对应的位并检查这些位是否都为1。 如果都为1则认为该元素可能存在于集合中如果有任何一个位为0则确定该元素不在集合中。 2简单使用布隆过滤器 首先安装模块 pip install pybloom_live使用示例 from pybloom_live import ScalableBloomFilter, BloomFilter# 创建一个可扩容的布隆过滤器 # initial_capacity容量 # error_rate错误率 bloom ScalableBloomFilter(initial_capacity100, error_rate0.001, modeScalableBloomFilter.LARGE_SET_GROWTH)# 添加元素 url1 https://www.example.com?keys154623valueqbz url2 https://www.example.com?valueqbzkeys154623 bloom.add(url1) bloom.add(url2)# 检测结果 print(len(bloom)) # 2 print(url1 in bloom) # True print(url2 in bloom) # True错误率测试 from pybloom_live import ScalableBloomFilterbloom ScalableBloomFilter(initial_capacity1000, error_rate0.01)for i in range(100000):data fexample{i}bloom.add(data)false_list [] for i in range(1000):data fexist{i}if bloom.__contains__(data):false_list.append(data)print(false_list) print(f错误率:{len(false_list)/100}%) # [exist29, exist49, exist53, exist118, exist144, exist196, exist215, exist219, exist235, exist259, exist293, exist331, exist339, exist377, exist404, exist421, exist451, exist494, exist551, exist615, exist665, exist750, exist760, exist821, exist831, exist832, exist983] # 错误率:0.27%3scrapy自定义过滤器没有关闭默认的 创建布隆过滤器中间件 from scrapy import signals from pybloom_live import ScalableBloomFilter from scrapy.exceptions import IgnoreRequest import hashlibclass BloomFilterMiddleware:def __init__(self, crawler):self.crawler crawler# 从Scrapy设置中读取布隆过滤器的配置self.initial_capacity crawler.settings.getint(BLOOM_FILTER_INITIAL_CAPACITY, 100000)self.error_rate crawler.settings.getfloat(BLOOM_FILTER_ERROR_RATE, 0.001)# 初始化布隆过滤器self.bloom_filter ScalableBloomFilter(initial_capacityself.initial_capacity, error_rateself.error_rate)classmethoddef from_crawler(cls, crawler):s cls(crawler)# 连接信号crawler.signals.connect(s.spider_opened, signalsignals.spider_opened)crawler.signals.connect(s.spider_closed, signalsignals.spider_closed)crawler.signals.connect(s.process_request, signalsignals.request_scheduled)return sdef spider_opened(self, spider):# 可以在这里加载之前保存的布隆过滤器状态如果需要的话passdef spider_closed(self, spider):# 可以在这里保存布隆过滤器的当前状态如果需要的话passdef process_request(self, request, spider):# 对URL进行哈希处理url_hash hashlib.sha256(request.url.encode()).hexdigest()# 检查URL是否已经在布隆过滤器中if url_hash in self.bloom_filter:# 如果可能在布隆过滤器中则忽略请求raise IgnoreRequest(URL already processed)def process_response(self, request, response, spider):# 检查响应是否成功if response.status 200:# 对URL进行哈希处理url_hash hashlib.sha256(request.url.encode()).hexdigest()# 将URL添加到布隆过滤器中self.bloom_filter.add(url_hash)return response在配置文件中注册 # 添加自定义中间件 MIDDLEWARES {your_project_name.middlewares.BloomFilterMiddleware: 542, }# 布隆过滤器设置 BLOOM_FILTER_INITIAL_CAPACITY 10000 # 根据你的需求设置容量 BLOOM_FILTER_ERROR_RATE 0.01 # 设置误报率
http://www.dnsts.com.cn/news/82387.html

相关文章:

  • 做公司集团网站网站建设合同用贴印花税吗
  • 开网站做商城怎么样vs2015做网站如何添加控件
  • 网站logo图怎么做wordpress引用文章
  • 网站新闻更新怎么设计网站开发的技术有
  • 毕节网站怎么做seowordpress球形标签
  • 国外做电商网站有哪些方面网页美工设计教程百度网盘
  • 中国公司网站建设方案网站可以制作ios
  • 简单的购物网站设计网站建设 amp 找VX cp5173
  • 外贸建站培训辽宁省工程建设招标网
  • wordpress添加背景游戏优化大师手机版
  • 前端网站做中 英文怎么说网站建设的频道是什么意思
  • 网站建设网络推广公司有哪些广西学校论坛网站建设
  • 做体彩网站怎么做西安博网站建设
  • 义乌公司网站制作网页制作和网站制作有什么区别
  • 高仿id97网站模板深圳网站开发找哪里
  • 如何创建电子商务网站南阳东莞网站建设公司哪家好
  • 满版型网站有哪些关闭网站后弹窗代码
  • 我想在阿里巴巴做卫生纸的网站安徽观元建设有限公司网站
  • 静安网站开发wordpress分享朋友圈
  • 可信赖的赣州网站建设游戏平台网站的建设规划
  • 泰安市景区建设网站呼和浩特 的网站建设
  • 公司的英文网站百度渠道开户哪里找
  • 网站优化包括哪些内容怎么做营销策划方案
  • 商务礼品网站模板免费永久网站注册
  • 做淘宝必备网站天津有哪些有名的网站建设公司
  • 上海微信网站开发益阳建设企业网站
  • 广州外贸soho建站微信群发软件
  • 网站的建设与预算哪些网站做推广
  • 遵义网站建设制作wordpress的链接功能
  • 如何与网站建立私密关系做网站网站代理违法吗