❶ 求帮忙解释一下下面两段python代码的基于scrapy的网络爬虫框架
简单的理解就是:
第一段解析网页内容,并提取需要的数据(这里涉及到很多python的基础知识);
第二段是将提取到的数据保存到文件。
❷ 怎么使用python脚本运行多个scrapy爬虫
1、创建多个spider, scrapy genspider spidername domain
scrapy genspider CnblogsHomeSpider cnblogs.com
通过上述命令创建了一个spider name为CnblogsHomeSpider的爬虫,start_urls为 、查看项目下有几个爬虫scrapy list
[root@bogon cnblogs]# scrapy list
CnblogsHomeSpider
CnblogsSpider
由此可以知道我的项目下有两个spider,一个名称叫CnblogsHomeSpider,另一个叫CnblogsSpider。
❸ python scrapy 怎么将爬取的内容写出
首先,安装Python,坑太多了,一个个爬。由于我是windows环境,没钱买mac, 在安装的时候遇到各种各样的问题,确实各种各样的依赖。安装教程不再赘述。如果在安装的过程中遇到 ERROR:需要windows c/c++问题,一般是由于缺少windows开发编译环境,晚上大多数教程是安装一个VisualStudio,太不靠谱了,事实上只要安装一个WindowsSDK就可以了。下面贴上我的爬虫代码:
爬虫主程序:
[python]view plain
#-*-coding:utf-8-*-
importscrapy
fromscrapy.httpimportRequest
fromzjf.FsmzItemsimportFsmzItem
fromscrapy.selectorimportSelector
#圈圈:情感生活
classMySpider(scrapy.Spider):
#爬虫名
name="MySpider"
#设定域名
allowed_domains=["nvsheng.com"]
#爬取地址
start_urls=[]
#flag
x=0
#爬取方法
defparse(self,response):
item=FsmzItem()
sel=Selector(response)
item['title']=sel.xpath('//h1/text()').extract()
item['text']=sel.xpath('//*[@class="content"]/p/text()').extract()
item['imags']=sel.xpath('//div[@id="content"]/p/a/img/@src|//div[@id="content"]/p/img/@src').extract()
ifMySpider.x==0:
page_list=MySpider.getUrl(self,response)
forpage_singleinpage_list:
yieldRequest(page_single)
MySpider.x+=1
yielditem
#init:动态传入参数
#命令行传参写法:scrapycrawlMySpider-astart_url="e_url"
def__init__(self,*args,**kwargs):
super(MySpider,self).__init__(*args,**kwargs)
self.start_urls=[kwargs.get('start_url')]
defgetUrl(self,response):
url_list=[]
select=Selector(response)
page_list_tmp=select.xpath('//div[@class="viewnewpages"]/a[not(@class="next")]/@href').extract()
forpage_tmpinpage_list_tmp:
ifpage_tmpnotinurl_list:
url_list.append("px/"+page_tmp)
returnurl_list
[python]view plain
#-*-coding:utf-8-*-
#Defineyouritempipelineshere
#
#Don'_PIPELINESsetting
fromzjfimportsettings
importjson,os,re,random
importurllib.request
importrequests,json
fromrequests_toolbelt.multipart.encoderimportMultipartEncoder
classMyPipeline(object):
flag=1
post_title=''
post_text=[]
post_text_imageUrl_list=[]
cs=[]
user_id=''
def__init__(self):
MyPipeline.user_id=MyPipeline.getRandomUser('37619,18441390,18441391')
#processthedata
defprocess_item(self,item,spider):
#获取随机user_id,模拟发帖
user_id=MyPipeline.user_id
#获取正文text_str_tmp
text=item['text']
text_str_tmp=""
forstrintext:
text_str_tmp=text_str_tmp+str
#print(text_str_tmp)
#获取标题
ifMyPipeline.flag==1:
title=item['title']
MyPipeline.post_title=MyPipeline.post_title+title[0]
#保存并上传图片
text_insert_pic=''
text_insert_pic_w=''
text_insert_pic_h=''
forimag_urlinitem['imags']:
img_name=imag_url.replace('/','').replace('.','').replace('|','').replace(':','')
pic_dir=settings.IMAGES_STORE+'%s.jpg'%(img_name)
urllib.request.urlretrieve(imag_url,pic_dir)
#图片上传,返回json
upload_img_result=MyPipeline.uploadImage(pic_dir,'image/jpeg')
#获取json中保存图片路径
text_insert_pic=upload_img_result['result']['image_url']
text_insert_pic_w=upload_img_result['result']['w']
text_insert_pic_h=upload_img_result['result']['h']
#拼接json
ifMyPipeline.flag==1:
cs_json={"c":text_str_tmp,"i":"","w":text_insert_pic_w,"h":text_insert_pic_h}
else:
cs_json={"c":text_str_tmp,"i":text_insert_pic,"w":text_insert_pic_w,"h":text_insert_pic_h}
MyPipeline.cs.append(cs_json)
MyPipeline.flag+=1
returnitem
#spider开启时被调用
defopen_spider(self,spider):
pass
#sipder关闭时被调用
defclose_spider(self,spider):
strcs=json.mps(MyPipeline.cs)
jsonData={"apisign":"","user_id":MyPipeline.user_id,"gid":30,"t":MyPipeline.post_title,"cs":strcs}
MyPipeline.uploadPost(jsonData)
#上传图片
defuploadImage(img_path,content_type):
"uploadImagefunctions"
#UPLOAD_IMG_URL="dpostimage"
UPLOAD_IMG_URL="oadpostimage"
#传图片
#imgPath='D:picshttp___img_nvsheng_com_uploads_allimg_170119_18-1f1191g440_jpg.jpg'
m=MultipartEncoder(
#fields={'user_id':'192323',
#'images':('filename',open(imgPath,'rb'),'image/JPEG')}
fields={'user_id':MyPipeline.user_id,
'apisign':'',
'image':('filename',open(img_path,'rb'),'image/jpeg')}
)
r=requests.post(UPLOAD_IMG_URL,data=m,headers={'Content-Type':m.content_type})
returnr.json()
defuploadPost(jsonData):
CREATE_POST_URL="hmagespost"
[python]view plain
reqPost=requests.post(CREATE_POST_URL,data=jsonData)
[python]view plain
defgetRandomUser(userStr):
user_list=[]
user_chooesd=''
foruser_idinstr(userStr).split(','):
user_list.append(user_id)
userId_idx=random.randint(1,len(user_list))
user_chooesd=user_list[userId_idx-1]
returnuser_chooesd
[python]view plain
#-*-coding:utf-8-*-
#
#
#Seedocumentationin:
importscrapy
classFsmzItem(scrapy.Item):
#:
#name=scrapy.Field()
title=scrapy.Field()
#tutor=scrapy.Field()
#strongText=scrapy.Field()
text=scrapy.Field()
imags=scrapy.Field()
这样就可以爬取aaa.com下的内容了
❹ python3 scrapy怎么爬取<div>内的多个<br>
我今天刚学了这个,你用xpath写好选择路径就会返回形成一个列表,列表中有你想要的信息
❺ 如何在scrapy框架下,用python实现爬虫自动跳转页面来抓去网页内容
(1)一种是像我之前爬虫新京报网的新闻,下一页的url可以通过审查元素获得,第一页的网址是http://www.bjnews.com.cn/news/list-43-page-1.html
在第一页的时候,下一页按钮的审查元素是
我们通过获取next_pages = response.xpath('//div[@id="page"]/a[@class="next"]/@href').extract()[0]
,便可以得到下一页的url,next_page = "http://www.bjnews.com.cn" + next_pages,
这一部分的完整代码为:
page_link=set() #保存下一页页面url
content_link=set() #保存页面内所有可获得的url
rules={'page':LinkExtractor(allow=(r'^http://www.bjnews.com.cn/\w+/2016/\d{2}/\d{2}/\d{6}.html
))}
start_urls={'http://www.bjnews.com.cn/news/list-43-page-1.html'}
def parse(self, response):
#爬取一个页面内的所有url链接
for link in self.rules['page'].extract_links(response):
if link.url not in self.content_link:
self.page_link.add(link.url)
yield scrapy.Request(link.url, callback=self.parse_item)
#自动获取下一页的url
next_pages = response.xpath('//div[@id="page"]/a[@class="next"]/@href').extract()[0]
if next_pages:
next_page = "http://www.bjnews.com.cn" + next_pages
self.page_link.add(next_page)
yield scrapy.Request(next_page, callback=self.parse)
(2)第二种情况,就是在下一页的审查元素中没有提供url链接,需要自己分析,在这里依然举个例子,比如搜狐新闻http://news.sohu.com/guojixinwen.shtml,该页中下一页按钮的审查元素是:
我们不能通过href来直接过得下一页的url,需要自己手动获得,那现在我们来分析
第二页的url:http://news.sohu.com/guojixinwen_5230.shtml,第三页的http://news.sohu.com/guojixinwen_5229.shtml,最后一页的http://news.sohu.com/guojixinwen_5132.shtml,由此可以分析出这一共100页的url,是http://news.sohu.com/guoneixinwen_"+i+".shtml",其中i是从5230到5132倒序排列的,也就是说通过for循环,就可以获得这100页的所有url,完整代码如下:在这里给大家加一个新的方法的使用start_request,该方法就是子定义start_urls,把所有自定义的url放到page_link中,self.make_requests_from_url方法会自动获取里面的请求
❻ 怎么样使用Python的Scrapy爬虫框架
有些人问,开发网络爬虫应该选择Nutch、Crawler4j、WebMagic、scrapy、WebCollector还是其他的?这里按照我的经验随便扯淡一下:
上面说的爬虫,基本可以分3类:
1.分布式爬虫:Nutch
2.JAVA单机爬虫:Crawler4j、WebMagic、WebCollector
3. 非JAVA单机爬虫:scrapy
第一类:分布式爬虫
爬虫使用分布式,主要是解决两个问题:
1)海量URL管理
2)网速
现在比较流行的分布式爬虫,是Apache的Nutch。但是对于大多数用户来说,Nutch是这几类爬虫里,最不好的选择,理由如下:
1)Nutch是为搜索引擎设计的爬虫,大多数用户是需要一个做精准数据爬取(精抽取)的爬虫。Nutch运行的一套流程里,有三分之二是为了搜索引擎而设计的。对精抽取没有太大的意义。也就是说,用Nutch做数据抽取,会浪费很多的时间在不必要的计算上。而且如果你试图通过对Nutch进行二次开发,来使得它适用于精抽取的业务,基本上就要破坏Nutch的框架,把Nutch改的面目全非,有修改Nutch的能力,真的不如自己重新写一个分布式爬虫框架了。
2)Nutch依赖hadoop运行,hadoop本身会消耗很多的时间。如果集群机器数量较少,爬取速度反而不如单机爬虫快。
3)Nutch虽然有一套插件机制,而且作为亮点宣传。可以看到一些开源的Nutch插件,提供精抽取的功能。但是开发过Nutch插件的人都知道,Nutch的插件系统有多蹩脚。利用反射的机制来加载和调用插件,使得程序的编写和调试都变得异常困难,更别说在上面开发一套复杂的精抽取系统了。而且Nutch并没有为精抽取提供相应的插件挂载点。Nutch的插件有只有五六个挂载点,而这五六个挂载点都是为了搜索引擎服务的,并没有为精抽取提供挂载点。大多数Nutch的精抽取插件,都是挂载在“页面解析”(parser)这个挂载点的,这个挂载点其实是为了解析链接(为后续爬取提供URL),以及为搜索引擎提供一些易抽取的网页信息(网页的meta信息、text文本)。
4)用Nutch进行爬虫的二次开发,爬虫的编写和调试所需的时间,往往是单机爬虫所需的十倍时间不止。了解Nutch源码的学习成本很高,何况是要让一个团队的人都读懂Nutch源码。调试过程中会出现除程序本身之外的各种问题(hadoop的问题、hbase的问题)。
5)很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等。很多人其实理解错了,这里说的持久化数据,是指将URL信息(URL管理所需要的数据)存放到avro、hbase、mysql。并不是你要抽取的结构化数据。其实对大多数人来说,URL信息存在哪里无所谓。
6)Nutch2的版本目前并不适合开发。官方现在稳定的Nutch版本是nutch2.2.1,但是这个版本绑定了gora-0.3。如果想用hbase配合nutch(大多数人用nutch2就是为了用hbase),只能使用0.90版本左右的hbase,相应的就要将hadoop版本降到hadoop 0.2左右。而且nutch2的官方教程比较有误导作用,Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x,这个Nutch2.x官网上写的是可以支持到hbase 0.94。但是实际上,这个Nutch2.x的意思是Nutch2.3之前、Nutch2.2.1之后的一个版本,这个版本在官方的SVN中不断更新。而且非常不稳定(一直在修改)。
所以,如果你不是要做搜索引擎,尽量不要选择Nutch作为爬虫。有些团队就喜欢跟风,非要选择Nutch来开发精抽取的爬虫,其实是冲着Nutch的名气(Nutch作者是Doug Cutting),当然最后的结果往往是项目延期完成。
如果你是要做搜索引擎,Nutch1.x是一个非常好的选择。Nutch1.x和solr或者es配合,就可以构成一套非常强大的搜索引擎了。如果非要用Nutch2的话,建议等到Nutch2.3发布再看。目前的Nutch2是一个非常不稳定的版本。
❼ scrapy和python有什么关系
Scrapy是Python开发的一个快速、高层次的web数据抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘和监测。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等。
Scrapy算得上是Python世界中最常用的爬虫框架了,同时它也是我掌握的几种流行语言中最好的爬虫框架,没有之一!我认为它也是最难学习的框架,同样没有之一。很多初学Scarpy的经常向我抱怨完全不清楚Scrapy该怎样入手,即使看的是中文的文档,也感到很难理解。我当初接触Scrapy时也有这样的感觉。之所以感到Scrapy难学,究其原因,是其官方文档实在太过凌乱,又缺少实用的代码例子,让人看得云里雾里,不知其所已然。虽然其文档不良,但却没有遮挡住它的光辉,它依然是Python世界中目前最好用的爬虫框架。其架构的思路、蜘蛛执行的效能,还有可扩展的能力都非常出众,再配以Python语言的简洁轻巧,使得爬虫的开发事半功倍。
相关推荐:《Python基础教程》
Scrapy的优点:
(1)提供了内置的HTTP缓存,以加速本地开发。
(2)提供了自动节演调节机制,而且具有遵守robots.txt的设置的能力。
(3)可以定义爬行深度的限制,以避免爬虫进入死循环链接。
(4)会自动保留会话。
(5)执行自动HTTP基本认证。不需要明确保存状态。
(6)可以自动填写登录表单。
(7)Scrapy有一个内置的中间件,可以自动设置请求中的引用(referrer)头。
(8)支持通过3xx响应重定向,也可以通过HTML元刷新。
(9)避免被网站使用的meta重定向困住,以检测没有JS支持的页面。
(10)默认使用CSS选择器或XPath编写解析器。
(11)可以通过Splash或任何其他技术(如Selenium)呈现JavaScript页面。
(12)拥有强大的社区支持和丰富的插件和扩展来扩展其功能。
(13)提供了通用的蜘蛛来抓取常见的格式:站点地图、CSV和XML。
(14)内置支持以多种格式(JSON、CSV、XML、JSON-lines)导出收集的数据并将其存在多个后端(FTP、S3、本地文件系统)中。
Scrapy框架原理
Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheler中间的通讯,信号、数据传递等。
Scheler(调度器):负责接收引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
Spider(爬虫):负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheler(调度器),
Item Pipeline(管道):负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
Scrapy各个组件介绍
·Scrapy Engine:
引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。它也是程序的入口,可以通过scrapy指令方式在命令行启动,或普通编程方式实例化后调用start方法启动。
·调度器(Scheler)
调度器从引擎接收爬取请求(Request)并将它们入队,以便之后引擎请求它们时提供给引擎。一般来说,我们并不需要直接对调度器进行编程,它是由Scrapy主进程进行自动控制的。
·下载器(Down-loader)
下载器负责获取页面数据并提供给引擎,而后将网站的响应结果对象提供给蜘蛛(Spider)。具体点说,下载器负责处理产生最终发出的请求对象 Request 并将返回的响应生成 Response对象传递给蜘蛛。
·蜘蛛——Spiders
Spider是用户编写用于分析响应(Response)结果并从中提取Item(即获取的Item)或额外跟进的URL的类。每个Spider负责处理一个特定(或一些)网站。
·数据管道——Item Pipeline
Item Pipeline 负责处理被 Spider 提取出来的 Item。 典型的处理有清理、验证及持久化(例如,存取到数据库中)。
·下载器中间件(Downloader middle-wares)
下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的Response。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy的功能。
·Spider中间件(Spider middle-wares)
Spider 中间件是在引擎及 Spider 之间的特定钩子(specific hook),处理 Spider 的输入(Response)和输出(Items及Requests)。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy的功能。
从Scrapy的系统架构可见,它将整个爬网过程进行了非常具体的细分,并接管了绝大多数复杂的工作,例如,产生请求和响应对象、控制爬虫的并发等。
❽ Python求助#SCRAPY pineline 报错
yielditem#这里不懂该怎么用,出来的是什么格式,#有的教程会returnitems,所以希望能得到指点yield生成器合理用内存,比如说数组里面有100个占100内存,而机器只有10内存那直接returnrange(100)就把内存撑爆,所有yield一个一个来即每次用1内存。fortmpinitem:#不知道这里是否写的对,#个人理解是spiderreturn出来的item是yileddict#[{a:1,aa:11},{b:2,bb:22},{}]对了一半,从报错信息来看,item有一部分是字符串类型一部分dict。你需过对tmp做个类型判断再做后缀操作相同点功能都是返回程序执行结果区别yield返回执行结果并不中断程序执行,return在返回执行结果的同时中断程序执行。小例子使用scrapy抓取网页时经常会使用for循环来抓取数据return实现items=[]forinitem['title']=items.append(item)returnitems123456123456yield实现forinitem['title']=yielditem
❾ 如何在scrapy框架下用python爬取json文件
#coding=utf-8
importsys
importscrapy
importurllib2
importre,requests,json
fromscrapy.httpimportRequest
reload(sys)
sys.setdefaultencoding('utf8')
classprojectSpider(scrapy.Spider):
name="youproject"
#allowed_domains=["youproject.com"]
start_urls=(
"http://p.3.cn/prices/mgets?&type=3652063&pid=3652063&skuIds=J_3652063",
#京东商品获取价格的链接
)
defparse(self,response):
#response.url是京东价格的例子,所请求的数据就是json,其请求后的数据为:[{"id":"J_3652063","p":"1299.00","m":"1499.00","op":"1299.00"}]
json_date=json.loads(response.body_as_unicode())
price=json_date[0]['p']#获取的就是price的价格
printprice#u'1299.00'