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

奶茶网站建设方案模板网络的推广

奶茶网站建设方案模板,网络的推广,seo一般包括哪些内容,网站开发选择什么软件一.基本情况 1.简介: Scrapy是1个为了爬取网站数据,提取结构性数据而编写的应用框架,可用于数据挖掘/信息处理/存储历史数据/监测/自动化测试等功能 其最初是为了网页抓取(更准确地说,网络抓取)而设计的,但也可用于获取API(如AWS)返回的数据或开发通用的网络爬虫 Scrapy框架使…

一.基本情况
1.简介:

Scrapy是1个为了爬取网站数据,提取结构性数据而编写的应用框架,可用于数据挖掘/信息处理/存储历史数据/监测/自动化测试等功能
其最初是为了网页抓取(更准确地说,网络抓取)而设计的,但也可用于获取API(如AWS)返回的数据或开发通用的网络爬虫
Scrapy框架使用了Twisted异步网络库来处理网络通讯,整体架构大致如下图:

在这里插入图片描述
2.主要组件:

①引擎(Scrapy Engine):用来处理整个系统的数据流,并触发事务.引擎通过触发事务带动了整
个项目的运行,是Scrapy框架的核心②调度器(Scheduler):用来接受引擎发过来的请求,压入队列中,并在引擎再次请求时返回.可以
想像成1个URL的优先队列,会决定下1个要抓取的网址是什么,并去除重复的网址③下载器(Downloader):用于下载网页内容,并将网页内容返回给爬虫.Scrapy的下载器是建立
在Twisted这个高效的异步模型上的④爬虫(Spiders):用于从特定的网页中提取需要的信息,即所谓的实体(Item);也可以从中提取
出链接,让Scrapy继续抓取下1个页面.另外,1个Scrapy项目中可以包含多个爬虫⑤项目与管道(Item and Item Pipeline):负责处理爬虫提取到的实体,主要功能是格式化实
体/持久化(即保存)实体/验证实体的有效性/清除无用的信息.当页面被爬虫解析后,将被发送到
项目管道,并经过几个特定的次序处理数据.注意,这部分可以写成2个组件,也可以写成1个⑥下载器中间件(Downloader Middlewares):位于Scrapy引擎和下载器之间的框架,主要用于
处理Scrapy引擎与下载器之间的请求及响应⑦爬虫中间件(Spider Middlewares):介于Scrapy引擎和爬虫之间的框架,主要用于是处理爬
虫的响应输入和请求输出⑧调度器中间件(Scheduler Middewares):位于Scrapy引擎和调度器之间的中间件,主要用于
处理Scrapy引擎与调度器之间的请求和响应

3.运行流程:

①爬虫中会有1个或多个起始URL
②引擎会把起始URL放入调度器
③引擎从调度器中取出1个链接(URL)用于接下来的抓取
④引擎把URL封装成1个请求(Request)传给下载器
⑤下载器把资源下载下来,并封装成应答包(Response)
⑥爬虫解析Response,调用回调函数
⑦解析出实体(Item),则交给实体和管道进行进一步的处理
⑧解析出链接(URL),则把URL交给调度器,等待之后抓取
⑨循环③到⑧,直到完成爬取

4.安装:

常见安装问题参见:https://blog.csdn.net/weixin_37797592/article/details/95527233

pip install scrapy

二.使用
1.基本命令:

scrapy startproject <pname>:创建Scrapy项目#执行后会在当前文件夹中创建1个与<pname>同名的文件夹#其中包含多个文件与spiders文件夹#参数说明:pname:指定项目名#只能包含数字/字母/下划线,必须以字母开头scrapy genspider [-t template] <sname> <domain>:创建爬虫#执行后会在spiders文件夹中创建1个与<sname>同名的.py文件#参数说明:sname:指定爬虫名domain:指定起始URL与爬取范围(即允许的域名)scrapy list:展示所有爬虫scrapy crawl <spname>[ --nolog]:执行指定爬虫#参数说明:spname:指定爬虫名称(爬虫文件中name属性的值)--nolog:不显示日志#默认会以debug模式执行,会显示执行日志(即所有执行了的操作)#实例:
E:\program>scrapy startproject scrapy1#会在当前文件夹中创建项目文件夹
New Scrapy project 'scrapy1', using template directory 'C:\Users\Euler\AppData\Roaming\Python\Python37\site-packages\scrapy\templates\project', created in:E:\program\scrapy1You can start your first spider with:cd scrapy1scrapy genspider example example.comE:\program>cd scrapy1#注意:一定要进入项目文件夹,否则创建的爬虫文件会被放在当前文件夹E:\program\scrapy1>scrapy genspider chouti dig.chouti.com
Created spider 'chouti' using template 'basic' in module:{spiders_module.__name__}.{module}#创建的爬虫文件会被放在spiders文件夹中E:\program\scrapy1>scrapy list
choutiE:\program\scrapy1>scrapy crawl chouti --nolog
<200 https://dig.chouti.com/>

2.项目结构:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.爬虫部分
(1)爬虫文件的结构:

#chouti.py:创建爬虫文件时,通常以网站域名命名
import scrapy#,sys,iosys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding="gb18030")
#在Windows上需要加这1行,否则在终端上显示不出来(存在编码问题);在其他系统中不需要class ChoutiSpider(scrapy.Spider):#创建类name='chouti'#爬虫名称(即<spname>),需要通过该名称运行爬虫,故不能省略allowed_domains=['chouti.com'#允许的域名,即只在该域名下爬取]start_urls=['http://dig.chouti.com/'#起始URL]def parse(self,response):#访问起始URL并获取结果后的回调函数(会自动调用)#不能改名,否则无法自动调用(可通过重写scrapy.Spider的start_requests()方法解决)#response中封装了响应的内容print(response.url)#响应来自的URLprint(response.text)#响应体中的内容,以文本格式返回(由response.body经过解码得到)print(response.body)#响应体中的内容,以字节类型返回print(response.meta["depth"])#当前深度

(2)选择器:

选择指定的标签:<sel_list>=<sel>.xpath("<slctr>")#参数说明:sel:指定从该Selector对象中进行选择slctr:指定选择器(由下面2部分内容构成);strsel_list:返回1个Selector对象构成的list#指定查找范围:
在整个文档中进行查找:"//<selector>"
在整个文档的直接子标签中进行查找:"/<selector>"#通常只有1个<html>
在上面方法的查找结果的直接子标签中查找:"//<selector>/<selector>"
在上面方法的查找结果中查找:"//<selector>//<selector>"
在当前Selector对象中进行查找:".//<selector>"
在当前Selector对象的直接子标签中进行查找:"./<selector>"#参数说明:selector:指定选择器(即下面部分的内容)#进行选择的选择器:这部分的选择其可以联合使用,放在多个[]中
所有指定类型的标签构成的列表:"<type>"
上述列表中的第n个元素:"<type>[<n>]"#注意:①这里n从1开始,如果为"<type>[0]",将永远返回空列表#    ②是的,这里返回的也是列表,而不是单个对象(´Д`)#    ③如果n超出了列表范围,也返回空列表
拥有指定属性的指定类型的标签的列表:"<type>[@<attr>]"
指定属性等于指定值的指定类型的标签的列表:"<type>[@<attr>='<val>']"
指定属性的值以指定值开始的指定类型的标签的列表:"<type>[starts-with(@<attr>,'val')]"
指定属性的值复合指定格式的指定类型的标签的列表:"<type>[re:test(@<attr>,'<reg>')]"
指定属性的值中包含指定值的标签的列表:"[]"#参数说明:type:指定标签类型,如div/an:指定第n个元素#注意:这里的n不是列表索引,而从1开始,<type>[0]会返回1个空列表attr:指定属性;strval:指定值;str#注意:如果选择器整体使用的是双(单)引号包裹,val就只能用单(双)引号包裹,即包裹选择器和val的引号必须不同reg:指定格式;为正则表达式构成的str#其他:
将列表中的Selector对象转换为str:<sel_list>.extract()#返回str list
将Selector对象列表中第1个元素转换为str并返回:<sel_list>.extract_first()#返回str
取查找结果中的文本:"<slctr>/text()"#结果仍是对象,需要使用.extract()转换
获取指定标签的指定属性的值:"<slctr>/@<attr>"#如果是//@<attr>,则获取指定标签及其后代标签的指定属性的值#实例:
>>> from scrapy.selector import Selector
>>> #注意:HtmlXPathSelector已被弃用,建议使用Selector
>>> from scrapy.http import HtmlResponse
>>> html="""<!DOCTYPE html>
... <html>
...     <head lang="en">
...         <meta charset="UTF-8">
...         <title></title>
...     </head>
...     <body>
...         <a id='r1'>aaaa</a>
...         <ul>
...             <li class="item-"><a id='i1' href="link.html">first item</a></li>
...             <li class="item-0"><a id='i2' href="llink.html">first item</a></li>
...             <li class="item-1"><a href="llink2.html">second item<span>vv</span></a></li>
...         </ul>
...         <div><a href="llink2.html">second item<div class='i' id='dd'>dddd</div></a></div>
...     </body>
... </html>"""
>>> response=HtmlResponse(url='http://example.com',body=html,encoding='utf-8')
>>> Selector(response)
<Selector xpath=None data='<html>\n    <head lang="en">\n        <...'>
>>> Selector(response=response).xpath('//a')
[<Selector xpath='//a' data='<a id="r1">aaaa</a>'>...(省略)]
>>> Selector(response=response).xpath('/html')
[<Selector xpath='/html' data='<html>\n    <head lang="en">\n        <...'>]
>>> Selector(response=response).xpath("//a[1]")
[<Selector xpath='//a[1]' data='<a id="r1">aaaa</a>'>, <Selector xpath='//a[1]' data='<a id="i1" href="link.html">first ite...'>, <Selector xpath='//a[1]' data='<a id="i2" href="llink.html">first it...'>, <Selector xpath='//a[1]' data='<a href="llink2.html">second item<spa...'>, <Selector xpath='//a[1]' data='<a href="llink2.html">second item<div...'>]
>>> Selector(response=response).xpath("//a[2]")
[]#这怎么回事?????
>>> Selector(response=response).xpath('//a/@id')
[<Selector xpath='//a/@id' data='r1'>...(省略)]
>>> Selector(response=response).xpath('//div[@id]')
[<Selector xpath='//div[@id]' data='<div class="i" id="dd">dddd</div>'>]
>>> Selector(response=response).xpath('//a[@id="i1"]')
[<Selector xpath='//a[@id="i1"]' data='<a id="i1" href="link.html">first ite...'>]
>>> Selector(response=response).xpath('//a[@id='i1']')File "<stdin>", line 1Selector(response=response).xpath('//a[@id='i1']')^
SyntaxError: invalid syntax
>>> Selector(response=response).xpath('//a[contains(@href,"link")]')
[<Selector xpath='//a[contains(@href,"link")]' data='<a id="i1" href="link.html">first ite...'>...(省略)]
>>> Selector(response=response).xpath('//a[starts-with(@href,"ll")]')
[<Selector xpath='//a[starts-with(@href,"ll")]' data='<a id="i2" href="llink.html">first it...'>...(省略)]
>>> Selector(response=response).xpath('//a[re:test(@href,".2\.html")]')
[<Selector xpath='//a[re:test(@href,".2\\.html")]' data='<a href="llink2.html">second item<spa...'>...(省略)]
>>> Selector(response=response).xpath('//a[@id="r1"]').extract()
['<a id="r1">aaaa</a>']
>>> Selector(response=response).xpath('/html/body/ul/li/a/@href').extract()
['link.html', 'llink.html', 'llink2.html']
>>> Selector(response=response).xpath('/html/body/ul/li/a/@href').extract_first()
'link.html'>>> Selector(response=response).xpath('//a[@id][@href]')
[<Selector xpath='//a[@id][@href]' data='<a id="i1" href="link.html">first ite...'>...(省略)]
>>> ul_list=Selector(response=response).xpath('//body/ul/li')
>>> for item in ul_list:
...     v=item.xpath('./a/span')
...     print(v)
...
[]
[]
[<Selector xpath='./a/span' data='<span>vv</span>'>]
>>> for item in ul_list:
...     v=item.xpath('//a/span')
...     print(v)
...
[<Selector xpath='//a/span' data='<span>vv</span>'>]
[<Selector xpath='//a/span' data='<span>vv</span>'>]
[<Selector xpath='//a/span' data='<span>vv</span>'>]

(3)实现深度:

#爬虫文件chouti.py中:
import scrapy
from scrapy.http import Requestclass ASpider(scrapy.Spider):name='chouti'allowed_domains=["chouti.com"]start_urls=["http://dig.chouti.com"]def parse(self,response):url="https://dig.chouti.com/exist"yield Request(url=url,callback=self.parse)#Request对象封装了用户的请求,在回调函数中yield该对象表示将请求放入调度器#url指定URL,callback指定回调函数
#在settings.py中加上以下代码:
DEPTH_LIMIT=1#指定爬取的深度
#如指定为1,则访问初始URL页面中的URL(记为URL1),但不访问URL1页面中的URL
#如果不指定,会爬取直到页面上不再有URL

(4)处理Cookie:

import scrapy
from scrapy.http.response.html import HtmlResponse
from scrapy.http import Request
from scrapy.http.cookies import CookieJarclass ChoutiSpider(scrapy.Spider):name="chouti"allowed_domains=["chouti.com"]start_urls=('https://dig.chouti.com/',)cookie_dict=Nonedef parse(self,response):cookie_obj=CookieJar()#创建1个CookieJar容器cookie_obj.extract_cookies(response,response.request)#response.request是response要响应的请求#在CookieJar容器中放入response和response.requestself.cookie_dict=cookie_obj._cookies#_cookies为域名与域名下的Cookies构成的dictyield Request(url:"https://dig.chouti.com/login",method="POST",body="phone=12345678901&password=aaabbbccc&oneMonth=1"#注意:请求体不支持使用字典headers={'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},cookies=cookie_obj._cookies#Cookiescallback=self.check_login#回调函数)def check_login(self,response):print(response.text)yield Request(#进行下1步操作(如点赞)url="https://dig.chouti.com",callback=self.like)def like(self,response):pass

4.格式化处理爬取到的数据

items用于定义数据存储模板以结构化爬取到的数据,然后把统一交给pipelines处理注意:
①这2部分可以写成1个组件,也可以写成2个组件
②当然,也可以在爬虫文件中直接进行处理

(1)项目部分:

#items.py中:
class ChoutiItem(scrapy.Item):#定义1个数据存储模板title=scrapy.Field()#创建1个字段href=scrapy.Field()
#chouti.py中:
class ChoutiSpider(scrapy.Spider):...(省略)def parse(self,response):from ..items import ChoutiItem#从上1级的items.py中导入ChoutiItemitem_obj=ChoutiItem(title=title,href=href)#封装数据yield item_obj#item对象用于结构化数据,在回调函数中yield该对象表示将其传递给pipeline

(2)管道部分:

#pipelines.py中:
from scrapy.exceptions import DropItemclass Scrapy1Pipeline:def __init__(self,conn_s):self.conn_s=conn_sself.conn=Nonedef open_spider(self,spider):#该函数在启动爬虫时执行self.f=open("news.json","a+")#self.conn=...#此处可以通过self.conn_s连接数据库def process_item(self,item,spider):#该函数处理传入的item对象,在yield item对象时执行#item为传入的item对象,spider为提交该对象的爬虫if spider.name=="chouti"#如果该对象来自chouti爬虫#因为所有爬虫提交的item对象都会被交给该类,所以需要进行判断,只对指定爬虫传递的对象执行相应操作print(item,spider)tpl="%s\n%s\n\n"%(item["title"],item["href"])#使用<item>["<field>"]获取相应字段的值self.f.write(tpl)return item#继续交给后续的pipeline对象进行处理def close_spider(self,spider):#该函数在关闭爬虫时执行self.f.close()@classmethoddef from_crawler(cls,crawler):#Scrapy内部使用该函数创建pipeline对象(不过没有也可以创建pipeline对象),并读取配置文件#cls为当前类的类名,crawler为conn_s=crawler.settings.getint('DB')#获取settings.py中DB选项的值(DB的值通过DB=<val>来指定)#注意:这里的选项必须全部大写!!!不能是'db'/'Db'/'dB'等╰_╯#可以在这里获取与数据库连接需要的内容return cls(conn_s)	#每个爬虫提交的每个对象都会被依次交给(顺序见下)所有爬虫
class Scrapy1Pipeline2:def process_item(self,item,spider):if spider.name=="cnblogs":print(item)raise DropItem()#抛出DropItem异常,将item对象丢弃,不再交给后续的pipeline对象进行处理#为便于监听丢弃item对象的时间,不要省略这1行
#settings.py:
ITEM_PIPELINES={'scrapy1.pipelines.Scrapy1Pipeline':300,#在这里注册的每个类都会被执行,且每个爬虫提交的每个对象都会被传递给所有类#key指定了Pipeline类#value(为int,通常属于[0,1000])则指定了执行顺序,值越小越先执行;为None则不执行'scrapy.pipelines.Scrapy1Pipeline2':200,
}

5.调度器
(1)去除重复的URL:

Scrapy默认使用scrapy.dupefilter.RFPDupeFilter类进行去重#相关配置(settings.py中):以下是默认内容,但没有明确写出
DUPEFILTER_CLASS='scrapy.dupefilter.RFPDupeFilter'#指定用于去重的类
DUPEFILTER_DEBUG=False
JOBDIR="保存范文记录的日志路径,如:/root/"#最终路径为 /root/requests.seen

(2)自定义去重:

#settings.py中:
DUPEFILTER_CLASS='day96.duplication.RepeatFilter'#指定用于去重的类#scrapy1/scrapy1/duplication.py中:
class RepeatFilter(BaseDupeFilter):def __init__(self, path=None, debug=False):self.visited_urls=set()#以下各函数都不能改名:@classmethoddef from_settings(cls, settings):#cls即当前类的类名(此处是RepeatFilter)#在内部会通过RepeatFilter.from_settings()创建RepeatFilter对象return cls()def request_seen(self, request):if request.url in self.visited_urls:return Trueelse:self.visited_urls.add(request.url)return Falsedef request_fingerprint(self,request):print("request_fingerprint")def close(self,reason):#爬取结束时执行print("close")def log(self,request,spider):#日志print("log")

三.通过钩子函数进行扩展:

1.钩子函数的概念:

钩子函数就是在特定事件发生时(收到特定信号时)自动触发的函数.将函数注册到指定信号上(挂
到特定的钩子上)就得到了相应的钩子函数

2.信号列表:

各个信号的含义参见:https://docs.scrapy.org/en/latest/topics/signals.html
https://blog.csdn.net/qq_41020281/article/details/82779919

#信号列表(scrapy\signals.py中):
engine_started = object()#Engine开始时
engine_stopped = object()#Engine结束时
spider_opened = object()#Spider开始时
spider_idle = object()#Spider进入空闲状态时
spider_closed = object()#Spider关闭时
spider_error = object()#Spider发生错误时
request_scheduled = object()#Engine调用Request时
request_dropped = object()#Request被Scheduler拒绝时
request_reached_downloader = object()#Request到达Downloader时
request_left_downloader = object()#Request离开Downloader时(不论因为什么)
response_received = object()#Engine从Downloader收到Response时
response_downloaded = object()#HTTPResponse被下载完成时
bytes_received = object()#收到字节数据时
item_scraped = object()#Item通过了所有Pipeline时
item_dropped = object()#Item被Pipeline丢弃时(抛出DropItem异常时)
item_error = object()#Pipeline发生DropItem外的异常时

3.在指定信号上注册钩子函数:

#默认的扩展类(scrapy\extensions\telnet.py中):
class TelnetConsole(protocol.ServerFactory):def __init__(self, crawler):...(省略)self.crawler.signals.connect(self.start_listening, signals.engine_started)self.crawler.signals.connect(self.stop_listening, signals.engine_stopped)#这里挂上了2个钩子函数,第1个参数是函数,第2个参数是钩子的名称(见 三.2 部分)...(省略)
#自定义扩展类(scrapy1/scrapy1/extensions.py中):from scrapy import signalsclass MyExtend:def __init__(self,crawler):#在__init__()或from_crawler()中挂载钩子函数均可self.crawler=crawlerself.crawler.signals.connect(self.e_start,signals.engine_started)@classmethoddef from_crawler(cls,crawler):return cls(crawler)def e_start(self):print("engine started")

4.注册扩展:

#默认的注册情况(settings.py):
#EXTENSIONS={
#    'scrapy.extensions.telnet.TelnetConsole':None
#}
#自定义注册(settings.py):
EXTENSIONS={'scrapy1.extensions.MyExtend':300,
}
#数值的作用和ITEM_PIPELINES中的相同,都代表权重
http://www.lbrq.cn/news/2743867.html

相关文章:

  • 投资建设项目管理师报名网站建立营销型网站
  • wordpress手机中文版下载地址谷歌seo优化排名
  • 黄金网站app软件下载安装免费seo自学网站
  • 可以做彩页的网站百度信息流投放
  • 可以建设个人网站百度网站登录
  • 网站开发行业提升神马关键词排名报价
  • 东营建网站wordpress建站公司
  • php做的网站怎么调试软文推广文章案例
  • 什么是品牌网站友情链接交换条件
  • 网图素材库seo的实现方式
  • 做网站找我图片seo优化广告
  • 模板网站音响案例baidu 百度一下
  • b2c 电子商务网站的经营特点企业网站排名优化公司
  • 做网站有的浏览器网站维护一般怎么做
  • 保险设计素材网站关于华大18年专注seo服务网站制作应用开发
  • 国内新闻最近新闻今天aso优化排名
  • 泰安建设网站短视频运营方案策划书
  • 黑龙江省seo网络营销案例分析
  • 网站建设 风险seo全网图文推广
  • 做营销网站国外最好的免费建站
  • 598网站建设想要网站导航正式推广
  • 山东企业网站建设公司泰州网站整站优化
  • cms做网站不用后端关键词优化需要从哪些方面开展
  • 网站登不上去的原因百度seo优化哪家好
  • 网站开发原则百度的合作网站有哪些
  • 简历制作免费模板网站企业邮箱怎么开通注册
  • 有域名 空间如何建网站广告推广方案怎么写
  • 内部网站建设、开源crm系统
  • 商城网站 备案seo搜索优化怎么做
  • 做线下极限运动的网站邵阳seo优化
  • c_str()函数的详细解析
  • geekbench riscv镜像下载
  • 什么是微前端?
  • [优选算法专题二滑动窗口——最大连续1的个数 III]
  • 基于单片机的防酒驾系统设计
  • 宋红康 JVM 笔记 Day02|JVM的架构模型、生命周期、发展历程