2017-03-28

入职接到的第一个小任务,scrapy多级页面爬虫,从来没写过爬虫,也没学过scrapy,甚至连xpath都没用过,最后用了将近一周才搞定。肯定有很多low爆的地方,希望大家可以给我一些建议。

spider文件:

# -*- coding: utf-8 -*-
import scrapy
from nosta.items import NostaItem
import time
import hashlib class NostaSpider(scrapy.Spider):
name = "nosta"
allowed_domains = ["nosta.gov.cn"]
start_urls = [
"http://www.nosta.gov.cn/upload/2017slgb/showProject.html",
] def parse(self, response):
for sel1 in response.xpath('//a/@href').extract():
# 存储链接自身组名group_name
group_name = response.xpath('//a[@href="%s"]/text()'%(sel1)).extract()[0]
# 存储链接前的顺序号group_number
group_number = response.xpath('//a[@href="%s"]/parent::*/preceding-sibling::*/text()'%(sel1)).extract()[0]
# 存储目录名directory_name
directory_name = response.xpath('//a[@href="%s"]/parent::*/parent::*/parent::*/parent::*/preceding-sibling::*/text()'%(sel1)).extract()[0]
# 存储链接本身group_url
group_url = response.urljoin(sel1)
# url1 = "http://www.nosta.gov.cn/upload/2017slgb/" + sel1
yield scrapy.Request(url = group_url, meta = {"group_name":group_name, "group_number":group_number, "directory_name":directory_name, "group_url":group_url}, callback=self.parse_url, dont_filter=True) def parse_url(self, response):
# item = response.meta['item']
group_name = response.meta["group_name"]
group_number = response.meta["group_number"]
directory_name = response.meta["directory_name"]
group_url = response.meta["group_url"]
for sel2 in response.xpath('//a/@href').extract():
# 存储链接前的顺序号project_number
project_number = response.xpath('//a[@href="%s"]/parent::*/preceding-sibling::*/text()'%(sel2)).extract()[0]
# 存储链接本身project_url
project_url = response.urljoin(sel2)
# 存储链接自身工程名project_name
project_name = response.xpath('//a[@href="%s"]/text()'%(sel2)).extract()[0]
# url2 = response.urljoin(sel2)
yield scrapy.Request(url = project_url, meta = {"group_name":group_name, "group_number":group_number, "directory_name":directory_name, "group_url":group_url, "project_number":project_number, "project_url":project_url, "project_name":project_name}, callback=self.parse_item, dont_filter=True) def parse_item(self, response):
item = NostaItem()
item["time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
item["year"] = [""]
item["group_name"] = response.meta["group_name"]
item["group_number"] = response.meta["group_number"]
item["directory_name"] = response.meta["directory_name"]
item["group_url"] = response.meta["group_url"]
item["project_number"] = response.meta["project_number"]
item["project_url"] = response.meta["project_url"]
item["project_name"] = response.meta["project_name"]
# 存储详情页源代码project_html
item["project_html"] = response.body
# 存储合作人关系链接file_urls
s1 = u'完成人合作关系说明:'
item["file_urls"] = ['http://www.nosta.gov.cn/upload/2017slgb'+i.replace('..', '') for i in response.xpath("//td[text() = '%s']/following-sibling::*/a/@href"%(s1)).extract()]
sha_1 = hashlib.sha1()
item["files"] = []
for i in item["file_urls"]:
dict1 = {}
dict1["url"] = i
sha_1.update(i)
dict1["path"] = sha_1.hexdigest() + ".pdf"
item["files"].append(dict1)
# 存储所有图片链接image_urls
item["image_urls"] = ['http://www.nosta.gov.cn/upload/2017slgb'+i.replace('..', '') for i in response.xpath('//img[@width="840px"]/@src').extract()]
# 存储所有图片本地地址和图片名(列表中存存字典)images
sha_2 = hashlib.sha1()
item["images"] = []
for i in item["image_urls"]:
dict2 = {}
dict2["url"] = i
sha_2.update(i)
dict2["path"] = sha_2.hexdigest() + ".jpg"
item["images"].append(dict2)
# 存储详情页中具体内容project_content
dict3 = {}
project_detail = response.xpath('//td[@class="label"]/text()').extract()
for j in project_detail:
dict3[j] = response.xpath("//td[text() = '%s']/following-sibling::*"%(j)).xpath('string(.)').extract()[0]
if not dict3[j]:
dict3[j] = ['http://www.nosta.gov.cn/upload/2017slgb'+i.replace('..', '') for i in response.xpath("//td[text() = '%s']/following-sibling::*/img/@src"%(j)).extract()]
item["project_content"] = dict3
yield item

items文件:

import scrapy

class NostaItem(scrapy.Item):
time = scrapy.Field()
files = scrapy.Field() # 完成人合作关系 列表中存字典 url:网上链接 path本地路径(第三级)
crawl_date = scrapy.Field() # 爬取日期
project_name = scrapy.Field() # 工程名称(第二、三级)
group_url = scrapy.Field() # 所在组的索引页面链接(第一、二级)
project_number = scrapy.Field() # 在组中顺序(第二级)
project_content = scrapy.Field() # 项目详情页中具体内容(第三级)
group_number = scrapy.Field() # 组在总页面中顺序(第一级)
project_url = scrapy.Field() # 项目链接(第二、三级)
group_name = scrapy.Field() # 组名称(第一、二、三级)
image_urls = scrapy.Field() # 列表存图片链接(第三级)
file_urls = scrapy.Field() # 列表中存合作人关系链接(第三级)
year = scrapy.Field() # 哪年(2017)
images = scrapy.Field() # 列表中存字典 url:网上链接 path:本地路径(第三级)
directory_name = scrapy.Field() # 属于何种目录名(第一级)
project_html = scrapy.Field() # 项目详情页html源代码(第三级)
current_count = scrapy.Field()

pipelines文件

from pymongo import MongoClient
from nosta.items import NostaItem class NostaPipeline(object):
def __init__(self):
self.client = MongoClient('IP', 27017) def process_item(self, item, spider):
if isinstance(item, NostaItem):
dict1 = {}
dict1["time"] = item["time"]
dict1["files"] = item["files"]
dict1["project_name"] = item["project_name"]
dict1["group_url"] = item["group_url"]
dict1["project_number"] = item["project_number"]
dict1["project_content"] = item["project_content"]
dict1["group_number"] = item["group_number"]
dict1["project_url"] = item["project_url"]
dict1["group_name"] = item["group_name"]
dict1["image_urls"] = item["image_urls"]
dict1["file_urls"] = item["file_urls"]
dict1["year"] = item["year"]
dict1["images"] = item["images"]
dict1["directory_name"] = item["directory_name"] self.db = self.client.nosta
self.db.authenticate('', '')
collection = self.db.nosta_2017
collection.insert(dict1) self.db = self.client.platform_info
self.db.authenticate('', '')
collection = self.db.crawl_info
dict2 = {}
dict2["current_count"] = item["current_count"]
if dict2["current_count"] == 1:
dict2["start_time"] = item["time"]
collection.update( {'job': '2017年国家科技奖励'}, {'$set': dict2}) return item

settings文件(部分修改)

ITEM_PIPELINES = {
'nosta.pipelines.NostaPipeline': 300,
'scrapy.pipelines.images.ImagesPipeline': 1,
'scrapy.pipelines.files.FilesPipeline': 1
} IMAGES_STORE = r'.'
FILES_STORE = r'.'

Python 自用代码(scrapy多级页面(三级页面)爬虫)的更多相关文章

  1. scrapy之盗墓笔记三级页面爬取

    #今日目标 **scrapy之盗墓笔记三级页面爬取** 今天要爬取的是盗墓笔记小说,由分析该小说的主要内容在三级页面里,故需要我们 一一解析 *代码实现* daomu.py ``` import sc ...

  2. Python 自用代码(知网会议论文网页源代码清洗)

    #coding=utf-8 from pymongo import MongoClient from lxml import etree import requests jigou = u" ...

  3. Python 自用代码(某方标准类网页源代码清洗)

    用于mongodb中“标准”数据的清洗,数据为网页源代码,须从中提取: 标准名称,标准外文名称,标准编号,发布单位,发布日期,状态,实施日期,开本页数,采用关系,中图分类号,中国标准分类号,国际标准分 ...

  4. Python 自用代码(递归清洗采标情况)

    将‘ISO 3408-1-2006,MOD  ISO 3408-2-1991,MOD  ISO 3408-3-2006,MOD’类似格式字符串存为: [{'code': 'ISO 3408-1-200 ...

  5. Python 自用代码(调整日期格式)

    2017年6月28日 to 2017-06-282017年10月27日 to 2017-10-272017年12月1日 to 2017-12-012017年7月1日 to 2017-07-01 #co ...

  6. Python 自用代码(拆分txt文件)

    现有一个28G的txt文件,里面每一行是一个分词过的专利全文文档,一共370多万行.我需要把它按每五万行为单位做成一个json文件,格式大致如下: [{"id":"100 ...

  7. Scrapy爬取静态页面

    Scrapy爬取静态页面 安装Scrapy框架: Scrapy是python下一个非常有用的一个爬虫框架 Pycharm下: 搜索Scrapy库添加进项目即可 终端下: #python2 sudo p ...

  8. Python开发入门与实战4-模板页面

    4.Django基于模板页面 在前一章中,HTML是直接被硬编码在 Python views.py代码中,如下: from django.http import HttpResponse import ...

  9. Python+Selenium爬取动态加载页面(2)

    注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...

随机推荐

  1. codeforces school mark(贪心)

    ///太渣,看了题解才知道怎么做,自己想感觉想不清楚 ///题解:首先在给出的序列里判断小于median的个数,若大于(n-1)/2,则不满足,否则看另一个条件 ///这样我们可以把中位数左边还要添加 ...

  2. 如何从oracle官网中下载The java language specification(java 语言规范)

    第一步: 第二步: 第三步:下面这个图在这个页面的下方,所以你只要一直往下看,直到看到下图的文字为止: 第四步: 第五步: 这样你就可以成功下载该java 语言规范的pdf了. 它直接下载的网址为: ...

  3. FreeFileSync

    FreeFileSync is an Open-Source folder comparison and synchronization tool. It is optimized for highe ...

  4. Welcome to Workrave

    Welcome to Workrave Workrave is a free program that assists in the recovery and prevention of Repeti ...

  5. ajax获取数据的处理和实例

    HTML: <!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" cont ...

  6. Android JSON

    转自:http://www.open-open.com/lib/view/open1326376799874.html JSON的定义: 一 种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性 ...

  7. Android消息推送解决方案

    前言 消息推送在Android开发中应用的场景是越来越多了,比如说电商产品进行活动宣传.资讯类产品进行新闻推送等等,如下图: 推送消息截图 本文将介绍Android中实现消息推送的7种主流解决方案 目 ...

  8. knockout 表单绑定 要怎么Mapping才好

    问题 之前有了解过knockout,学习过绑定语法,结合帮助文档,做个Demo倒也不成问题,但是部分地方很不爽,不知道是我的用法不对,还是功力不够. 比如说,标签里定义的data-bind属性名,必须 ...

  9. itoa()函数和sprintf()函数

    itoa()函数 itoa 为c语言的一个函数.itoa 函数是一个广泛应用的,从非标准扩展到标准的C语言.它不能被移植,因为它不是标准定义下的C语言,但是,编译器通常在一个不遵循程式标准的模式下允许 ...

  10. Web常用方法

    1.返回一个json格式报文 /**     * 返回json格式字符串或普通字符串     *      * @param jsonString     */    protected void w ...