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. div样式

    DIV样式汇总 一.常用属性: 1.Height:设置DIV的高度. 2.Width:设置DIV的宽度. 例: <div style="width:200px;height:200px ...

  2. display:table-cell的min-height

    table-cell的元素min-height是不起作用的,直接使用height就行,当高度不足时,table会自动拉伸cell元素. 此时,height相当于min-height. 出处:https ...

  3. 【CF Round 439 C. The Intriguing Obsession】

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  4. APIO2017游记

    铁牌选手爆零滚粗记QAQ........ CCF说不让讨论APIO相关内容不过现在应该没事了吧QAQ day0:上午还在学校填清北夏令营的表,下午上火车去北京,晚上颓颓颓...... day1:上午网 ...

  5. 《R语言实战》读书笔记 第七章--基本统计分析

    在导入数据并且将数据进行组织和初步可视化以后,需要对数据进行分布探索和两两关系分析等.主要内容有描述性统计分析.频数表和列联表.相关系数和协方差.t检验.非参数统计. 7.1描述性统计分析 7.1.1 ...

  6. COMPANY_点取消会卡死的解决方法

    // OLD void ctonedlg::onbtn_basedir_clicked() {     m_basedir = getUserSelectDir();     doSearchDir( ...

  7. C语言中的“>>”和“<<”

    http://baike.1688.com/doc/view-d1750791.html C语言中的“>>”和“<<” [标签:程序设计] 浏览次数:68937提问时间:200 ...

  8. Error:Execution failed for task ':bearBabyClient:processDebugManifest'. > Manifest merger failed with multiple errors, see logs

    具体报错如上: 在右侧中 大方块圈中的[com.android.support:support-v4:26.0.0-alpha1] 这个文件导致的,在这的清单文件第27行合并失败,让使用tools:r ...

  9. WinForm Control.Invoke&Control.BeginInvoke异步操作控件实例

    参考:http://www.cnblogs.com/yuyijq/archive/2010/01/11/1643802.html 效果图: 实例(实验)代码: using System; using ...

  10. java模拟生日发祝福

    1.新建customer表生日都选为当天 所需jar包 2.使用c3p0连接到数据的xml配置文件 3.连接数据库的工具类 package com.cc.birthday; import java.s ...