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. 洛谷 P3765 总统选举 解题报告

    P3765 总统选举 题目背景 黑恶势力的反攻计划被小C成功摧毁,黑恶势力只好投降.秋之国的人民解放了,举国欢庆.此时,原秋之国总统因没能守护好国土,申请辞职,并请秋之国人民的大救星小C钦定下一任.作 ...

  2. 添加对WCF的调用(内网状态下)。

    在能连接到内网的电脑上,运行SvcUtil.exe工具即可. 如打开文件后闪退,则可打开cmd后,将文件拖入到cmd中,然后再加上文件的地址.

  3. jquery 追加元素的方法(append prepend after before 的区别)

    append() 方法在被选元素的结尾插入内容. prepend() 方法在被选元素的开头插入内容. after() 方法在被选元素之后插入内容. before() 方法在被选元素之前插入内容. &l ...

  4. Uva 10158 War

    并查集的应用 直接阔成2倍.后N项为对应的敌人 #include <map> #include <set> #include <list> #include < ...

  5. msvc交叉编译:使用vcvarsall.bat设置命令行编译环境

    一直以来我只知道vc设置命令行编译环境的批处理命令是%VS140COMNTOOLS%/Common7/Tools下的vsvars32.bat,(%VS140COMNTOOLS%为定义vs2015公共工 ...

  6. Kubernetes监控工具

    #镜像在谷歌上需要FQ#####################################监控工具#当前最新版本 heapster https://github.com/kubernetes/h ...

  7. pymongo.errors.BulkWriteError错误排解

    在mongodb进行数据库操作的时候触发异常   pymongo Error: pymongo.errors.BulkWriteError: batch op errors occurred 这种问题 ...

  8. django的url匹配流程

    URL匹配流程(路由解析顺序): URL匹配流程说明 域名.端口.端口后的 /,以及查询字符串(问号后面的键值参数)不参与匹配 先到项目下的 urls.py 进行匹配,再到应用的 urls.py 匹配 ...

  9. js比对一维数组全等的算法

    //辅助方法1,返回某个值在数组中的位置 Array.prototype.indexOf = function (e) { for (var i = 0, l = this.length; i < ...

  10. jquery mloading

    在执行jQuery的ajax时,有的时候请求回来会有较长时间,这个时候,如果什么都没有显示,用户会觉得网站卡住了,所以这个时候,来个mloading会使用户体验更好些. 使用方法很简单 将jquery ...