为使项目框架结构清晰,添加的spider的按城市划分存储位置。
例如宁波新闻网—综合频道,则在spiders下面建一个ningbo(宁波)的文件夹,将该版面的spider写在该文件夹下面。
项目设计框架图:
实际项目tree图片见附件tree.jpg
webcrawler:.
|——scrapy.cfg
|——webcrawler:
|——items.py
|——pipelines.py
|——settings.py
|——__init__.py
|——spiders
|__init__.py
|——cityAAA
|——website_channel_type_id_spider|——cityBBB
|——website_channel_type_id_spider
|——city***
***
|——increment
|——cityAAA
|——website_channel_type_id.txt
|——cityBBB
|——website_channel_type_id_.txt
|——city***
***
|——logs(待实现)
|——cityAAA
|——website_channel_type_id.log |——cityBBB
|——website_channel_type_id.log
|——warnlog
|——warn.log
数据的存储位置在spider中指定
spider的创建步骤(以环球网--海外看中国版面为例):
1.在所在城市的文件加下创建spider(eg:环球网--海外看中国)
在spiders下面创建文件夹,名称为(quanguo)全国:
mkdir quanguo
进入文件夹,在文件夹下创建**_spider,命名规则为website_channel_type_id_spider.py,:
cd quanguo
vim huanqiu_oversea_new_1_spider.py
再创建一个名称为__init__.py的文件,该文件是运行py的必需文件,创建命令为:
touch __init__.py
2.进入创建的spider文件中,导入程序所需的包:
#coding=utf-8
import sys
sys.path.insert(0,'..')
import scrapy
import time
import os
import hashlib
import struct
from scrapy import Spider
import sys
from webcrawler.items import TextDetailItem
reload(sys)
sys.setdefaultencoding('gbk')
3.设置参数,包括增量文件的位置,
存储增量的incrementurls变量,首次采集的数量,文件存储的位置,日志存储的位置。
incrementurl=[]
indexUrl=''
fListNum=0
firstCrawlerNum=100
incrementfile="/download/Scrapy-1.0.1/webcrawler/webcrawler/increment/quanguo/huanqiu_oversea_new_1.txt"
sourceDefault="环球网--海外看中国"
savefile="/download/datastore/"
4.创建spider类,继承自Spider,并设置spider的运行name,allowed_urls,start_urls,保存采集数据的文件名称,读取增量文件获取urls(用于采集增量爬取数据,防止数据重复)
name="huanqiu_oversea_new_1_spider"
allowed_urls=["oversea.huanqiu.com"]
start_urls=["http://oversea.huanqiu.com/"]
#fetch time start
tempa=time.strftime('%Y-%m-%d',time.localtime(time.time()))
filename=time.mktime(time.strptime(tempa,'%Y-%m-%d'))
filename=str(filename)[0:10]
global savefile
savefile+="news_doc_incoming_1_"+filename
#fetch time end
#Read increment file start
global indexUrl
global incrementfile
global incrementurl
indexUrl="http://oversea.huanqiu.com/"
indexUrl=start_urls[0]
if os.path.isfile(incrementfile):
print('file have exist...')
else:
f=open(incrementfile,"w")
f.close()
furl = open(incrementfile, "r")
while True:
line = furl.readline()
if line=='':
break
else:
incrementurl.append(line.strip('\n'))
furl.close()
#Read increment file end
5.重写__init__函数,此函数继承自Spider,可不写,第四部的编码也可以写到该函数当中
def __init__(self):
print('init...')
6.编写parse(self,response)函数,对列表页的数据进行爬取,包括:
1.获取列表url
2).获取下一页的url
3).下一页的判断逻辑
4).判断url是否在增量中存在,若存在说明后面的数据已经采集过,break
5).根据url获取其详情页的内容
6).设置首次采集的数量,因为很多列表数据是分页的,首次采集无增量,采集的数据可能非常多
7).将第一页的列表url数据存储为增量url
8).进入列表页下一页的采集
def parse(self,response):
global indexUrl
global fListNum
global firstCrawlerNum
#获取请求的url,即(start_urls)
pUrl=str(response.url)
sel=scrapy.Selector(response)
#定义获取列表url
list=sel.xpath("//div[@class='leftList']/ul[@name='contentList']/li[@name='item']")
print(str(len(list)))
#获取下一页的url
nextUrl=sel.xpath("//div[@class='turnPage']/a/@href").extract()
#下一页的判断逻辑
if nextUrl is not None and len(nextUrl)>1:
nextPage=nextUrl[1]
elif nextUrl is not None and len(nextUrl)>0:
nextPage=nextUrl[0].encode('utf-8')
else:
nextPage=None
#定义增量标志
flag='0'
#依次获取列表中的每隔url,title可不提取,只为测试方便
for single in list:
title=single.xpath("a/dl/dt/h3/text()").extract()
url=single.xpath("a/@href").extract()
tempurl=url[0].encode('utf-8')
detailurl=tempurl
print(detailurl)
#判断该url是否在增量中存在,若存在说明后面的数据已经采集过,break
if detailurl in incrementurl:
flag='1'
break
else:
#根据url获取其详情页的内容
reqdetail=scrapy.Request(url=detailurl,meta={'pUrl':pUrl},callback=self.parse_detail)
yield reqdetail
#设置首次采集的数量,因为很多列表数据是分页的,首次采集无增量,采集的数据可能非常多
if len(incrementurl)==0:
fListNum+=len(list)
if(fListNum>firstCrawlerNum):
return
#将第一页的列表url数据存储为增量url
if indexUrl==str(response.url):
writeStr=''
for tSingle in list:
tUrl=tSingle.xpath("a/@href").extract()
ttUrl=tUrl[0].encode('utf-8')
writeStr+=ttUrl+'\n'
open(incrementfile,'w').write(writeStr+'\n')
#进入列表页下一页的采集
if flag=='0':
if nextPage is not None:
req = scrapy.Request(url=nextPage, callback=self.parse)
yield req
else:
return
7. 定义详情页采集函数,设置提取详情页数据的规则,将数据放进对象容器,供pipline存储
def parse_detail(self,response):
global savefile
global sourceDefault
#创建数据容器对象,用于存储采集的数据
textDetail=TextDetailItem()
sel=scrapy.Selector(response)
#定义提取详情页标题,来源,发布时间,正文的规则
title=sel.xpath("//div[@class='conText']/h1/text()").extract()
source=sel.xpath("//*[@id='source_baidu']/a/text()").extract()
source2=sel.xpath("//*[@id='source_baidu']/text()").extract()
tTime=sel.xpath("//strong[@id='pubtime_baidu']/text()").extract()
contents=sel.xpath("//div[@id='text']/p").extract()
url=response.url
if not url:
return
else:
#根据详情页url生成MD
tmp_msg_id = hashlib.md5(url).hexdigest()[0:8]
msg_id = long(struct.unpack('Q',tmp_msg_id)[0])
MD=msg_id
textDetail['MD']=str(MD)
textDetail['CL']="news"
textDetail['UR']=str(url)
PR=response.meta['pUrl']
textDetail['PR']=str(PR)
FC="0"
textDetail['FC']=FC
HR=str(response.status)
textDetail['HR']=HR
ET="0"
textDetail['ET']=ET
RT="1"
textDetail['RT']=RT
title=title[0].encode('utf-8')
print("text title:"+str(title))
textDetail['TI']=title
SR= sourceDefault
if len(source)>0:
SR=source[0].encode('utf-8')
else:
if len(source2)>0:
SRstr=source2[0].encode('utf-8')
SRstr=SRstr.replace("\r\n","")
SRstr=SRstr.strip()
SR=SRstr[9:]
textDetail['SR']=SR
imageurls=''
imageurls=''
#提取正文中的图片链接
imagelist=sel.xpath("//div[@id='text']/*/img[@src]/@src").extract()
for i in range(len(imagelist)):
if i==len(imagelist)-1:
imageurls+=imagelist[i]
else:
imageurls+=imagelist[i]+'|'
imageurls=imageurls.strip()
textDetail['IU']=str(imageurls)
textDetail['KW']=""
temptime=tTime[0].strip()
temptime=time.mktime(time.strptime(temptime,'%Y-%m-%d %H:%M:%S'))
PT=(str(temptime))[0:10]
textDetail['PT']=PT
dTime=time.time()
DT=(str(dTime))[0:10]
textDetail['DT']=DT
textDetail['TY']=""
content=""
for i in range(0, len(contents)):
content+=contents[i].encode('utf-8')
# content=content[0].encode('utf-8')
TX=content
textDetail['TX']=TX
textDetail['SP']=savefile
return textDetail
8.一次运行scrapy下所有spider的方法:查找资料后编写了一个crawlall.py,该python脚本能够获取到scrapy框架下所有的可运行的spider,并启动它,crawlall脚本代码如下:
from scrapy.commands import ScrapyCommand
from scrapy.crawler import CrawlerRunner
from scrapy.utils.conf import arglist_to_dict
class Command(ScrapyCommand):
requires_project = True
def syntax(self):
return '[options]'
def short_desc(self):
return 'Runs all of the spiders'
def add_options(self, parser):
ScrapyCommand.add_options(self, parser)
parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",
help="set spider argument (may be repeated)")
parser.add_option("-o", "--output", metavar="FILE",
help="dump scraped items into FILE (use - for stdout)")
parser.add_option("-t", "--output-format", metavar="FORMAT",
help="format to use for dumping items with -o")
def process_options(self, args, opts):
ScrapyCommand.process_options(self, args, opts)
try:
opts.spargs = arglist_to_dict(opts.spargs)
except ValueError:
raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)
def run(self, args, opts):
#settings = get_project_settings()
spider_loader = self.crawler_process.spider_loader
for spidername in args or spider_loader.list():
print "*********cralall spidername************" + spidername
self.crawler_process.crawl(spidername, **opts.spargs)
self.crawler_process.start()
9.可持续运行的shell脚本runspider.sh,通过运行脚本可持续的运行crawlall.py,runspider.sh脚本内容如下:
#!/bin/sh
int=1
while((1))
do
echo $int
scrapy crawlall
let "int++"
done
分享到:
相关推荐
**J2EE Spider** 是一个基于Java的代码生成工具,主要设计用于简化J2EE应用程序的开发过程。它通过自动创建常见的业务逻辑和数据访问层代码,帮助开发者节省时间并提高开发效率。J2EE Spider的目标是让开发者可以...
【标题】"Macro-SpiderWeb.zip_Spiderweb_gisdk" 提供了一个关于使用GISDK(Geographic Information System Development Kit)构建蜘蛛网图的详细教程。在地理信息系统(GIS)领域,蜘蛛网图是一种常见且实用的数据...
实现网络蜘蛛时,我们需要创建一个【队列】来存储待访问的URL,每次从队列头部取出一个URL,下载其内容并解析其中的链接。同时,为了防止重复访问,我们需要用到【哈希表】。哈希表允许我们快速查找和插入URL,确保...
在这个Eclipse项目中,Spider被设计为一个Java开发的工具,充分体现了Java在大数据处理领域的优势。 ### Spider引擎核心特性 1. **多线程处理**:Spider采用了多线程技术,能够同时处理多个网页抓取任务,极大地...
在本项目中,我们可能有一个名为`sogouimg`的Spider,负责处理搜狗图片的爬取逻辑。 3. **下载器中间件**:下载器中间件处理Scrapy发送的请求和接收的响应,可以用于添加自定义的请求头、处理反爬机制等。 4. **...
1. **配置启动器**:首先,你需要创建一个`Spider`实例,指定起始URL和解析规则。 2. **定义处理器**:通过自定义`PageProcessor`,你可以定义如何解析HTML页面,提取需要的信息。 3. **设置线程数**:根据需求...
`SpiderWebServer` 是一个由EPITA(École d'Ingénieurs en Informatique et Techniques Associées,法国计算机科学与信息技术工程师学院)的学生团队开发的项目,成员包括Clément NEGRE、Julien CROS、Nicolas ...
3. Spider将第一个URL发送给调度器。 4. 调度器返回队列中的URL给Engine,Engine通过中间件将URL发送给下载器请求页面。 5. 下载器下载完成后,将响应结果发送给Engine,Engine再转发给Spider。 6. Spider处理响应,...
yield item # 将Item传递给下一个处理步骤 ``` 然后,你可以运行Scrapy命令启动爬虫: ```bash scrapy crawl myspider ``` 这个简单的例子展示了如何使用Scrapy框架来抓取指定网址的内容。实际项目中,你可能需要...
1. **新建项目和爬虫文件**:使用`scrapy startproject project_name`命令创建一个新的Scrapy项目,接着使用`scrapy genspider spider_name domain.com`创建一个爬虫文件。 2. **定义数据结构**:在`items.py`文件中...
2. 创建Django项目和应用:初始化Django项目,并创建一个用于数据展示的应用。 3. 设计数据库模型:根据需求定义数据模型,以便Django能自动创建数据库表。 4. 编写Scrapy爬虫:创建Scrapy项目,定义Spider以抓取...
创建一个Scrapy项目通常包括以下步骤: 1. 安装Scrapy:`pip install scrapy` 2. 创建项目:`scrapy startproject project_name` 3. 在项目目录下创建Spider:`cd project_name && scrapy genspider spider_name ...
1. **创建PageProcessor**:这是核心部分,我们需要定义一个类实现`PageProcessor`接口,并重写`process(Page)`方法。在这个方法中,我们将解析网页HTML,找到文章标题的CSS选择器或XPath表达式,然后提取出文章标题...
- **初始化**: 构造函数`__init__`中打开一个名为`CNKI_data.json`的文件,并以写模式(`wb`)和UTF-8编码初始化。 - **处理数据**: `process_item`方法中,将每个`Item`转换为字典格式,并将其序列化为JSON字符串后...
编码工具 Visual Studio Code 实现步骤 1.创建scrapyTest项目 在vscode中新建终端并依次输入下列代码: scrapy startproject scrapyTest cd scrapyTest code 打开项目scrapyTest(vscode自动生成下列文件) 2.源...
"月影无痕采集器v1.1插件 for Phpcms 2008 GBK.rar" 是一个专为Phpcms 2008内容管理系统设计的数据采集工具,适用于GBK编码环境。该插件的主要功能是自动抓取网络上的信息,帮助用户快速填充和更新网站内容,提高...
- **定义爬虫类**:每个爬虫都是一个继承自 `scrapy.Spider` 的类。 - **编写爬虫逻辑**:通过定义 `start_urls`、`parse` 方法等来实现具体的抓取逻辑。 3. **选择器(Selectors)**:Scrapy 提供了两种类型的...
1. **创建Scrapy项目**:使用`scrapy startproject project_name`命令初始化一个新的Scrapy项目。 2. **定义Spider**:编写Spider类,指定要爬取的URL、解析规则(使用XPath或CSS选择器)以及如何提取数据。 3. **...
快速开始网络爬虫的学习,作者首先引导读者创建一个新的PyCharm项目,命名为"WebSpider",并创建一个名为"Spider001.py"的Python文件。通过编写简单的代码,读者可以立即感受到网络爬虫的效果。这段代码导入了`...
创建一个Scrapy项目,我们需要定义Item(要抓取的数据模型)、Spider(爬虫类)以及Pipeline(数据处理流程)。Scrapy的使用极大地提高了爬虫项目的组织和可维护性。 Python爬虫项目通常涉及以下几个步骤: 1. **...