Python:新浪网分类资讯爬虫
生活随笔
收集整理的這篇文章主要介紹了
Python:新浪网分类资讯爬虫
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
爬取新浪網導航頁所有下所有大類、小類、小類里的子鏈接,以及子鏈接頁面的新聞內容。
效果演示圖:
?
?
items.py
import scrapy
import sys
reload(sys)
sys.setdefaultencoding("utf-8")class SinaItem(scrapy.Item):# 大類的標題 和 urlparentTitle = scrapy.Field()parentUrls = scrapy.Field()# 小類的標題 和 子urlsubTitle = scrapy.Field()subUrls = scrapy.Field()# 小類目錄存儲路徑subFilename = scrapy.Field()# 小類下的子鏈接sonUrls = scrapy.Field()# 文章標題和內容head = scrapy.Field()content = scrapy.Field()
spiders/sina.py
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-from Sina.items import SinaItem
import scrapy
import osimport sys
reload(sys)
sys.setdefaultencoding("utf-8")class SinaSpider(scrapy.Spider):name= "sina"allowed_domains= ["sina.com.cn"]start_urls= ["http://news.sina.com.cn/guide/"]def parse(self, response):items= []# 所有大類的url 和 標題parentUrls = response.xpath('//div[@id=\"tab01\"]/div/h3/a/@href').extract()parentTitle = response.xpath("//div[@id=\"tab01\"]/div/h3/a/text()").extract()# 所有小類的ur 和 標題subUrls = response.xpath('//div[@id=\"tab01\"]/div/ul/li/a/@href').extract()subTitle = response.xpath('//div[@id=\"tab01\"]/div/ul/li/a/text()').extract()#爬取所有大類for i in range(0, len(parentTitle)):# 指定大類目錄的路徑和目錄名parentFilename = "./Data/" + parentTitle[i]#如果目錄不存在,則創建目錄if(not os.path.exists(parentFilename)):os.makedirs(parentFilename)# 爬取所有小類for j in range(0, len(subUrls)):item = SinaItem()# 保存大類的title和urlsitem['parentTitle'] = parentTitle[i]item['parentUrls'] = parentUrls[i]# 檢查小類的url是否以同類別大類url開頭,如果是返回True (sports.sina.com.cn 和 sports.sina.com.cn/nba)if_belong = subUrls[j].startswith(item['parentUrls'])# 如果屬于本大類,將存儲目錄放在本大類目錄下if(if_belong):subFilename =parentFilename + '/'+ subTitle[j]# 如果目錄不存在,則創建目錄if(not os.path.exists(subFilename)):os.makedirs(subFilename)# 存儲 小類url、title和filename字段數據item['subUrls'] = subUrls[j]item['subTitle'] =subTitle[j]item['subFilename'] = subFilenameitems.append(item)#發送每個小類url的Request請求,得到Response連同包含meta數據 一同交給回調函數 second_parse 方法處理for item in items:yield scrapy.Request( url = item['subUrls'], meta={'meta_1': item}, callback=self.second_parse)#對于返回的小類的url,再進行遞歸請求def second_parse(self, response):# 提取每次Response的meta數據meta_1= response.meta['meta_1']# 取出小類里所有子鏈接sonUrls = response.xpath('//a/@href').extract()items= []for i in range(0, len(sonUrls)):# 檢查每個鏈接是否以大類url開頭、以.shtml結尾,如果是返回Trueif_belong = sonUrls[i].endswith('.shtml') and sonUrls[i].startswith(meta_1['parentUrls'])# 如果屬于本大類,獲取字段值放在同一個item下便于傳輸if(if_belong):item = SinaItem()item['parentTitle'] =meta_1['parentTitle']item['parentUrls'] =meta_1['parentUrls']item['subUrls'] = meta_1['subUrls']item['subTitle'] = meta_1['subTitle']item['subFilename'] = meta_1['subFilename']item['sonUrls'] = sonUrls[i]items.append(item)#發送每個小類下子鏈接url的Request請求,得到Response后連同包含meta數據 一同交給回調函數 detail_parse 方法處理for item in items:yield scrapy.Request(url=item['sonUrls'], meta={'meta_2':item}, callback = self.detail_parse)# 數據解析方法,獲取文章標題和內容def detail_parse(self, response):item = response.meta['meta_2']content = ""head = response.xpath('//h1[@id=\"main_title\"]/text()')content_list = response.xpath('//div[@id=\"artibody\"]/p/text()').extract()# 將p標簽里的文本內容合并到一起for content_one in content_list:content += content_oneitem['head']= headitem['content']= contentyield item
pipelines.py
from scrapy import signals
import sys
reload(sys)
sys.setdefaultencoding("utf-8")class SinaPipeline(object):def process_item(self, item, spider):sonUrls = item['sonUrls']# 文件名為子鏈接url中間部分,并將 / 替換為 _,保存為 .txt格式filename = sonUrls[7:-6].replace('/','_')filename += ".txt"fp = open(item['subFilename']+'/'+filename, 'w')fp.write(item['content'])fp.close()return item
settings.py
BOT_NAME = 'Sina'SPIDER_MODULES = ['Sina.spiders']
NEWSPIDER_MODULE = 'Sina.spiders'ITEM_PIPELINES = {'Sina.pipelines.SinaPipeline': 300,
}LOG_LEVEL = 'DEBUG'
在項目根目錄下新建main.py文件,用于調試
from scrapy import cmdline
cmdline.execute('scrapy crawl sina'.split())
執行程序
py2 main.py
總結
以上是生活随笔為你收集整理的Python:新浪网分类资讯爬虫的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql中的递归层次查询(父子查询,无
- 下一篇: CentOS7 service netw