数据收集与处理(爬虫技术)

文章目录

  • 1 前言
  • 2 网络爬虫
    • 2.1 构造自己的Scrapy爬虫
      • 2.1.1 items.py
      • 2.1.2 spiders子目录
      • 2.1.3 pipelines.py
    • 2.2 构造可接受参数的Scrapy爬虫
    • 2.3 运行Scrapy爬虫
      • 2.3.1 在命令行运行
      • 2.3.2 在程序中调用
    • 2.4 运行Scrapy的一些要点
  • 3 大规模非结构化数据的存储与分析
  • 4 全部代码

1 前言

  • 介绍几种常见的数据收集、存储、组织以及分析的方法和工具
  • 首先介绍如何构造自己的网络爬虫从网上抓取内容,并将其中按照一定结构组织的信息抽取出来
  • 然后介绍如何使用ElasticSearch来有效地存储、组织和查询非结构化数据
  • 最后简要介绍和使用Spark对大规模的非结构化数据进行初步分析的方法

2 网络爬虫

2.1 构造自己的Scrapy爬虫

  • 在终端输入scrapy startproject money163,会自动生成一个同名的子目录和一个scrapy.cfg配置文件

  • 在这里插入图片描述

  • 有两个init文件都是空白的,暂时不用管,将经历放在items.py、settings.py、pipelines.py和将要在spiders子目录下生成的爬虫程序上

  • 基本结构建立起来之后,需要按照说明的步骤一次完成对内容抽取,爬虫目标和行为以及数据操作的定义,每一个定义都对应一个文件。

2.1.1 items.py

  • 在这个文件里面定义需要抽取的内容,这基本上是通过定义一个继承于scrapy.Item的内容类来完成的,每一个内容都属于scrapy.Field(),定义非常简单,即内容名称 = scrapy.Field()

2.1.2 spiders子目录

  • 在spiders子目录下新建一个python文件,假设命名为money_spider.py
  • 这个文件比较复杂,可以继承不同的类来定义
  • 首先使用Scrapy的CrawlSpider类,定义三个内容:一是爬虫的名字,二是目标网站,包括爬取模式和对返回链接的过滤等;三是返回的对象按照其结构抽取所需要的数据
  • 在money_spider.py文件中输入以下代码,注意将Stock163换成money163
# encoding: utf-8
import scrapy
import re
from scrapy.selector import Selector
from stock163.items import Stock163Item
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class ExampleSpider(CrawlSpider):
    name = "stocknews" #爬虫的名字为 "stocknews"
    allowed_domains = ["money.163.com"]#设置允许爬取的域名

    def __init__(self, id='600000', page='0', *args, **kwargs):#初始化方法,设置了一些初始参数,包括 id(默认为 '600000')、page(默认为 '0'),以及其他可能传递的参数。
        # allowrule = "/%s/%s\d+/\d+/*" % (year, month)
        # allowrule = "/%s/%s%s/\d+/*" % (year, month, day) #这个规则匹配类似 "/2022/11/25/" 这样的日期结构
        allowrule = r"/\d+/\d+/\d+/*"# 定义了一个正则表达式,用于匹配新闻链接的规则。数字 数字 数字 任意字符
        self.counter = 0 # 初始化一个计数器,可能用于跟踪爬取的新闻数量。
        self.stock_id = id  # 保存股票ID
        self.start_urls = ['http://quotes.money.163.com/f10/gsxw_%s,%s.html' % (id, page)] # 设置初始爬取的URL,这里使用了 id 和 page 参数构造URL。
        ExampleSpider.rules = (Rule(LinkExtractor(allow=allowrule), callback="parse_news", follow=False),)
        # 定义了爬取规则。这里使用了 LinkExtractor 来提取链接,通过正则表达式 allow=allowrule 匹配链接规则,然后指定了回调函数为 parse_news
        # 最后设置 follow=False 表示不跟踪从当前链接提取的链接。
        # recompile the rule
        super(ExampleSpider, self).__init__(*args, **kwargs)
        # 调用父类(CrawlSpider)的初始化方法,确保爬虫的正确初始化。

    '''
    rules=Rule(LinkExtractor(allow=r"/\d+/\d+/\d+/*"),
               callback="parse_news", follow=True
    )
    '''

    # f = open("out.txt", "w")

    def printcn(suni):
        for i in suni:
            print(suni.encode('utf-8'))

    def parse_news(self, response):
        item = Stock163Item()
        item['news_thread'] = response.url.strip().split('/')[-1][:-5]
        #这行代码从响应的URL中提取新闻线程信息。它首先通过response.url获取当前页面的URL,然后使用strip()方法去除首尾的空格,接着使用split('/')方法根据斜杠切割URL为一个列表,最后通过[-1]
        #取列表的最后一个元素,即URL中最后一个斜杠后的部分。[: -5] 是为了去掉文件扩展名(假设是.html或类似的扩展名),剩下的部分就是新闻线程的信息,然后将其赋值给item对象的news_thread属性。
        self.get_thread(response,item)
        self.get_title(response, item)
        self.get_source(response, item)
        self.get_url(response, item)
        self.get_news_from(response, item)
        self.get_from_url(response, item)
        self.get_text(response, item)

        return item  ##############!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!remenber to Retrun Item after parse

    def get_title(self, response, item):
        title = response.xpath("/html/head/title/text()").extract()
        if title:
            # print ('title:'+title[0][:-5].encode('utf-8'))
            item['news_title'] = title[0][:-5]

    def get_source(self, response, item):
        source = response.xpath("//div[@class='left']/text()").extract()
        if source:
            # print ('source'+source[0][:-5].encode('utf-8'))
            item['news_time'] = source[0][:-5]

    def get_news_from(self, response, item):
        news_from = response.xpath("//div[@class='left']/a/text()").extract()
        if news_from:
            # print 'from'+news_from[0].encode('utf-8')
            item['news_from'] = news_from[0]

    def get_from_url(self, response, item):
        from_url = response.xpath("//div[@class='left']/a/@href").extract()
        if from_url:
            # print ('url'+from_url[0].encode('utf-8')        )
            item['from_url'] = from_url[0]

    def get_text(self, response, item):
        news_body = response.xpath("//div[@id='endText']/p/text()").extract()
        if news_body:
            # for  entry in news_body:
            #     print (entry.encode('utf-8'))
            item['news_body'] = news_body

    def get_url(self, response, item):
        news_url = response.url
        if news_url:
            print(news_url)
        item['news_url'] = news_url


2.1.3 pipelines.py

  • 接着需要对所抽取的具体要素进行处理,要么显示在终端的窗口中,要么存入某个地方或者数据库中,现在我们假设将所抽取出来的要素构造成一个词典,以JSON文档的格式存为文本文件,每个页面单独存成一个文件。
  • 这个时候需要定义一个类,这个类里面只有一个方法,process_item(self,item,spider)
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
#encoding: utf-8
import os
def ParseFilePath(url, id):
    # user should change this folder path
    outfolder = "e:\\data\\FinTech\\News\\Stocks\\%s" % id
    components = url.split("/")
    year = components[3]
    monthday=components[4]
    month = monthday[:2]
    day = monthday[2:]
    idx=components[5]
    page=idx+"_"+components[6]
    #folder = outfolder + "\\%s_%s_%s_" % (year, month, day)
    folder = outfolder
    if ((year=='') | ('keywords' in page)):
       filepath='xxx'
    else:
       filepath = folder + "\\%s_%s_%s_%s.txt" % (year, month, day, page) 
    filepath=filepath.replace('?', '_')
    return(folder, filepath)

class Stock163Pipeline(object):   
    def process_item(self, item, spider):
        if spider.name != "stocknews":  return item
        if item.get("news_thread", None) is None: return item
                
        url = item['news_url']
        if 'keywords' in url:
           return item
        folder, filepath = ParseFilePath(url, spider.stock_id)
        spider.counter = spider.counter+1
        counterfilepath = folder+"\\counter.txt"
        #one a single machine will is virtually no risk of race-condition
        if not os.path.exists(folder):
           os.makedirs(folder)        
        #print(filepath, counterfilepath)
        #print(spider.stats)
        fo = open(counterfilepath, "w", encoding="UTF-8")
        fo.write(str(spider.counter))
        fo.close()

        if (filepath!='xxx'):
           fo = open(filepath, 'w', encoding='utf-8')
           fo.write(str(dict(item)))
           fo.close()
        return None
        

2.2 构造可接受参数的Scrapy爬虫

  • 这节内容主要介绍能改变起始网页的地址,从而使得同一个爬虫爬去不同的网站
  • 修改来start_urls,同时也修改了allowed_domain,保证爬虫顺利进行,最后通过super方法执行这个类,来更新参数
`class ExampleSpider(CrawlSpider):
    name = "stocknews"
    

    def __init__(self, id='600000', page='0', *args, **kwargs):        
        #allowrule = "/%s/%s\d+/\d+/*" % (year, month)
        allowrule = "/%s/%s%s/\d+/*" % (year, month, day)         
        self.counter = 0
        self.stock_id = id
        self.start_urls = ['http://\%s' \% (site)]
        ExampleSpider.rules=(Rule(LinkExtractor(allow=allowrule), callback="parse_news", follow=False),)
        #recompile the rule        `

2.3 运行Scrapy爬虫

  • 一种是在命令行里面执行crawl命令,一种是在别的程序中调用Scrapy爬虫
  • 命令行中是单线程,程序调用是多线程,一次可以同时爬取不同的网站,当然也可以通过twisted包里面的internet.defer方法来将每个爬虫串联起来,同时调用reactor来控制执行顺序
  • Scrapy也可以在多台机器上部署分布式

2.3.1 在命令行运行

  • 在命令行中非常简单,进入项目的主目录,即包含scrapy.cfg文件的那个目录,输入:scrapy crawl money163,这里的money163是在spider.py程序文件中使用“ name=“money163”定义的爬虫名字,crawl是让Scrapy爬虫开始爬去网页“scrapy craw money163 -a site = money.163.com/stock

2.3.2 在程序中调用

  • 在别的程序里调用Scrapy爬虫可以使用不同的类,这里使用CrawlerProcess类,配合get_project_setting方法,就可以在项目目录中非常方面地使用别的程序运行自己的爬虫
    -首先引入相应的模块和函数
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
  • 然后定义爬虫过程,在定义的过程中,先通过get_project_settings获取项目的信息,再传给所定义的爬虫过程 process = CrawlerProcess(get_project_settings())
  • 定义好爬虫过程后,只需调用这个过程对象,包括传递参数,就能运行爬虫了,比如:process.crawl('stocknews', id=stockid, page=str(page))
  • 按照列表中的三个网址定义了三个爬虫,最后通过process.start来启动爬虫,因为使用了get_project_settings,这个python程序需要在项目所在目录下执行才能有效运行
for site in ['money.163.com', 'tech.163.com', 'money.163.com/stock']: 
	process.crawl('myspider', site = site)
process.start()

2.4 运行Scrapy的一些要点

  • 有些网站会对网络请求是否是网络爬虫进行识别,如果发现是网络爬虫,则会进行约束,比如限制流量甚至直接拒绝响应
  • 因此需要合理设置setting.py和middleware文件里面的选项来实现

3 大规模非结构化数据的存储与分析

  • 非结构化的数据是指没有定义结构的数据,一种典型的非结构化数据是文本,包括日期、数字、人名、事件等,这样的数据没有规则可循
  • 比如数据挖掘、自然语言处理、文本分析等提供了不同方法从非结构化数据里找出模式,处理文本常用的技巧通常涉及到元数据或者词性标签手动标记
  • 非结构化数据一般使用schema.org定义的类型和属性作为标记(比如JSON- LD)
  • 当单个网页上有多种实体类型时,这些实体应该都被标记,例如视频schemma.org/VideoObject

4 全部代码

from keras.applications.vgg16 import VGG16
from keras.layers import Input,Flatten,Dense,Dropout
from keras.models import Model
from keras.optimizers import SGD

from keras.datasets import mnist

import cv2
import h5py as h5py
import numpy as np

model_vgg = VGG16(include_top=False,weights='imagenet',input_shape=(ishape,ishape,3))
model = Flatten(name='flatten')(model_vgg.output)
model = Dense(4096,activation='relu',name='fc1')(model)
model = Dense(4096,activation='relu',name='fc2')(model)
model = Dropout(0.5)(model)
model = Dense(10,activation='softmax')(model)
model_vgg_mnist = Model(model_vgg.input,model,name='vgg16')

model_vgg_mnist.summary()

model_vgg = VGG16(include_top=False,weights='imagenet',input_shape=(224,224,3))
for layer in model_vgg.layers:
    layer.trainable=False
model = Flatten()(model_vgg.output)
model = Dense(4096,activation='relu',name='fc1')(model)
model = Dense(4096,activation='relu',name='fc2')(model)
model = Dropout(0.5)(model)
model = Dense(10,activation='softmax',name='prediction')(model)
model_vgg_mnist_pretrain = Model(model_vgg.input,model,name='vgg16_pretrain')

model_vgg_mnist_pretrain.summary()

sgd = SGD(lr = 0.05,decay=1e-5)
model_vgg_mnist_pretrain.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])

(x_train,y_train),(x_test,y_test) = mnist.load_data()
x_train = [cv2.cvtColor(cv2.resize(i,(ishape,ishape)),cv2.COLOR_GRAY2BGR) for i in x_train]
x_train = np.concatenate([arr[np.newaxis] for arr in x_train]).astype('float32')
x_test = [cv2.cvtColor(cv2.resize(i,(ishape,ishape)),cv2.COLOR_GRAY2BGR) for i in x_test]
x_test = np.concatenate([arr[np.newaxis] for arr in x_test]).astype('float32')

x_test.shape
x_train.shape

x_train /= 255
x_test /= 255

np.where(x_train[0]!=0)

def tran_y(y):
    y_ohe = np.zeros(10)
    y_ohe[y] = 1
    return y_ohe

y_train_ohe = np.array([tran_y(y_train[i]) for i in range(len(y_train))])
y_test_ohe = np.array([tran_y(y_test[i]) for i in range(len(y_test))])

model_vgg_mnist_pretrain.fit(x_train,y_train_ohe,validation_data=(x_test,y_test_ohe),epochs=200,batch_size=128)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/205974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

建文工程项目管理软件 SQL 注入漏洞复现

0x01 产品简介 建文工程管理软件是一个适用于工程投资领域的综合型的多方协作平台。 0x02 漏洞概述 建文工程项目管理软件BusinessManger.ashx、Desktop.ashx等接口处存在SQL注入漏洞,攻击者可通过该漏洞获取数据库中的信息(例如,管理员后台…

TypeScript 5.3

导入属性 TypeScript 5.3支持导入属性提案的最新更新。 导入属性的一个用例是向运行库提供有关模块预期格式的信息。 // We only want this to be interpreted as JSON, // not a runnable/malicious JavaScript file with a .json extension. import obj from "./somet…

【综述+自动流量分析A】New Directions in Automated Traffic Analysis

文章目录 论文简介摘要存在的问题论文贡献1. 整体架构2. nPrint3. nPrintML4. 任务 总结论文内容工具数据集可读的引用文献笔记参考文献 论文简介 原文题目:New Directions in Automated Traffic Analysis 中文题目:自动流量分析的新方向 发表会议&#…

Java多线程-第20章

Java多线程-第20章 1.创建线程 Java是一种支持多线程编程的编程语言。多线程是指在同一程序中同时执行多个独立任务的能力。在Java中,线程是一种轻量级的子进程,它是程序中的最小执行单元。Java的多线程编程可以通过两种方式实现:继承Threa…

windows配置使用supervisor

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、使用步骤1.安装supervisor-win2.配置supervisord3.配置program4.启动supervisord.exe5.supervisorctl.exe管控 二、后台启动总结 前言 windows使用supervi…

PromptRank:使用Prompt进行无监督关键词提取

论文题目:PromptRank: Unsupervised Keyphrase Extraction Using Prompt   论文日期:2023/05/15(ACL 2023)   论文地址:https://arxiv.org/abs/2305.04490   GitHub地址:https://github.com/HLT-NLP/PromptRank 文章目录 Ab…

虽然在不同设备上会出现同样的原神错误代码9907,但解决办法因设备而异

你是不是很享受在原神(Genshin Impact)中的神奇旅程,但错误代码9907出现了?与PS4控制台中全面讨论PS4的错误CE-34878-0不同,本文关注的是原神错误本身。本文不仅讨论了这个错误背后的原因,还讨论了每种类型设备的具体解决方案。 在Microsoft Windows/PC上修复错误代码99…

NSSCTF第14页(2)

[UUCTF 2022 新生赛]ezpop 提示说看看反序列化字符串逃逸 PHP反序列化字符串逃逸_php反序列化逃逸-CSDN博客 php反序列化字符逃逸_php反序列化逃逸_Leekos的博客-CSDN博客 buuctf刷题9 (反序列化逃逸&shtml-SSI远程命令执行&idna与utf-8编码漏洞)_extract($_post);…

Linux 基本语句_12_信号

用途: 信号可以直接进行用户进程与内核进程之间的交互 特性: 对于一个进程,其可以注册或者不注册信号,不注册的信号,进程接受后会按默认功能处理,对于注册后的信号,进程会按自定义处理 自定义…

vue3 keep-alive页面切换报错:parentComponent.ctx.deactivate is not a function

问题&#xff1a; <router-view v-slot"{ Component }"><keep-alive ><component :is"Component" v-if"$route.meta.keepAlive" /></keep-alive><component :is"Component" v-if"!$route.meta.keepA…

FFmpeg之将视频转为16:9(横屏)或9:16(竖屏)(一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

全网最牛最全面的Jmeter接口测试:jmeter_逻辑控制器_事务控制器

事务&#xff1a; 性能测试中&#xff0c;事务指的是从端到端&#xff0c;一个完整的操作过程&#xff0c;比如一次登录、一次 筛选条件查询&#xff0c;一次支付等&#xff1b;技术上讲&#xff1a;事务就是由1个或多个请求组成的 事务控制器 事务控制器类似简单控制器&…

Selenium——isDisplayed()、isEnabled()、isSelected()

判断页面是否存在某元素 Selenium没有直接提供判断是否存在的方法&#xff0c;可以使用findElements返回的数量判断&#xff1b;或者判断findElement是否抛出异常 webDriver.findElements(By.xpath("(//div[classel-button-group]//button)[1]")).size()isDisplaye…

分享72个简历竞聘PPT,总有一款适合您

分享72个简历竞聘PPT&#xff0c;总有一款适合您 72个简历竞聘PPT下载链接&#xff1a;https://pan.baidu.com/s/1EGqu8ufs8nh45NliNniWuQ?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整…

BUUCTF john-in-the-middle 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附件&#xff0c;解压得到john-in-the-middle.pcap文件。 解题思路&#xff1a; 1、双击文件&#xff0c;打开wireshark。 看到很多http流…

Go 语言输出文本函数详解

Go语言拥有三个用于输出文本的函数&#xff1a; Print()Println()Printf() Print() 函数以其默认格式打印其参数。 示例 打印 i 和 j 的值&#xff1a; package mainimport "fmt"func main() {var i, j string "Hello", "World"fmt.Print(…

深入学习redis-基于Jedis通过客户端操作Redis

目录 redis客户端&#xff08;JAVA&#xff09; 配置 引入依赖 建立连接 常用命令实现 get/set exists/del keys expire和ttl type 字符串&#xff08;String&#xff09; mget和mset getrange和setrange append incr和decr 列表&#xff08;list&#xff09; …

【C++ Primer Plus学习记录】循环和文本输入

目录 1.使用原始的cin进行输入 2.使用cin.get(char)进行补救 3.使用哪一个cin.get() 4.文件尾条件 循环完后的一项最常见、最重要的任务&#xff1a;逐字符地读取来自文件或键盘的文本。 cin对象支持3种不同模式的单字符输入&#xff0c;其用户接口各不相同。下面介绍如何…

一种快速设计射频功放IC流程分享

No.1设计目标 在功率放大器PA中&#xff0c;输出级以及输出匹配决定了该功放的线性度、效率等关键性能指标&#xff0c;通常被优先考虑。在这个项目中输出级功放关键性能指标如下&#xff1a; 带宽&#xff1a;12-13 GHz OP1dB>13dBm 输出级 Power gain>5dB DE_P1dB&…

K歌利器-无线K歌麦克风模组-投影K歌解决方案

麦克风K歌模组是一种用于改善音频质量的麦克风系统&#xff1b;其发展可以追溯到20世纪50年代&#xff0c;如今&#xff0c;麦克风模组的技术发展已经非常成熟&#xff0c;可以提供更为优质的音频质量&#xff1b;支持多种不同的连接方式&#xff1b;可以在不同的设备上使用。 …