分享

审计中使用爬虫获取粮食交易价格

 hl1bwcdm 2020-06-30

每一个交易公告点开后有详细的交易信息:

他们应该是需要获取公告的交易数量、价格等信息。

朋友很不错向我发了他的代码,里面用的是selenium,xlwings等库。

由于selenium是需要打开关闭浏览器,稍微复杂了点,而且效率比较差。并且xlwings库是操作excel的,他是想将爬取的数据保存到excel里,其实这里也不需要这么复杂。

由于这个网址比较简单,我就直接用scrapy爬虫框架快速写了下代码,获取该数据,作为大家学习交流,有兴趣的可以自学一下scrapy库。

下面我讲解下使用scrapy爬取数据的全过程:

抓包分析

首先,我们用chrome浏览器打开目标网址:

http://www./news!list.action?code=25

按F12后刷新页面,抓包分析。

点击“network'可以看到很多session,如果不知道是哪一个可以在左边的搜索框内搜索页面上的一些文字,找到我们需要的session,然后点击,当然这里我们就是第一个session.

在session中我们点击“Headers'就可以分析请求的网址,header等请求头信息。

这个网址比较简单,只需要用到url网址信息就行。我们通过点击”response'可以看到返回的是html标签。

这里我们点击下“小箭头”再点击下网页中我们需要的公告标题,可以看到对应的html标签。

没错标题就存在<div class='news_list'>标签下的a标签中,里面有相对网址和标题信息。

我们通过获取该标签下的a标签就可以拿到所有的详情页的网址。

然后,再把详情的的信息通过正则表达式提取出来。

基本上分析工作就到这里了。

知识点:chrome浏览器F12抓包分析。

新建scrapy项目

在新建前,需要安装scrapy库,安装方法使用pip命令安装

pip install scrapy

安装完成后,新建一个项目

scrapy startproject rice

在终端上输入上述命令后,会在本地新建一个文件夹rice(这个是自定义的)

├── rice
│   ├── __init__.py
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   ├── items.cpython-38.pyc
│   │   └── settings.cpython-38.pyc
│   ├── riceoutput.csv
│   ├── settings.py
│   └── spiders
│       ├── __init__.py
│       ├── __pycache__
│       │   ├── __init__.cpython-38.pyc
│       │   └── ricedata.cpython-38.pyc
│       └── ricedata.py
├── scrapy.cfg

可以看到新建了rice文件夹和一堆文件,不要恐慌。

这里我们不展开讲scrapy,因为可以讲一天,他其实是一个把很多功能给我们写好了的脚手架,我们只需要添加一些东西就可以运行,省去写很多代码。

我们进入到“spider”文件夹,生成一个爬虫文件,取名为ricedata

scrapy genspider ricedata www.

最后的网址就是我们目标网站的域名。

在终端运行该命令后,就会在spider文件夹下生成ricedata.py这个文件。

下面我们所有的工作就是编辑item.py和reicedata.py两个文件。

编写数据字段

打开item.py文件

import scrapy


class RiceItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()
    volumn = scrapy.Field()
    price = scrapy.Field()
    method = scrapy.Field()
    warehouse = scrapy.Field()
    title = scrapy.Field()

我们需要把框架中自动生成的类RiceItem填写上我需要的字段,类是自动创建的,我们只是添加了name = scrapy.Field()这样的字段。

这些字段是什么意思呢?可以看到最终我们需要获取到的文本信息有,品名(name),成交量(volumn),成交价格(price),等等。我们这里只是给它们命名下。告诉电脑,我最终获取的数据包含这些字段。

编写爬虫

我们打开ricedata.py文件,编写爬虫

# -*- coding: utf-8 -*-
# author:nigo
import scrapy
import re
from urllib import parse
from rice.items import RiceItem


class RicedataSpider(scrapy.Spider):
    name = 'ricedata'
    allowed_domains = ['']
    start_urls = ['http://www./news!list.action?code=25']

    def parse(self, response):
        link_elements = response.xpath('//div[@class='news_list']//a'# 所有链接A标签
        next_page = response.xpath('//a[text()='下一页']/@href').extract_first() #获取下一页相对地址
        next_page_url = parse.urljoin(response.url, next_page) # 组装下一页地址 # 下一页绝对地址
        for link_element in link_elements: # 循环标题列表每个a标签
            title = link_element.xpath('./text()').extract_first() # 公告标题
            link = link_element.xpath('./@href').extract_first() # 详情页相对链接
            if re.findall('成交公告$',title): # 判断如果为成交公告则爬取详情页信息
                url = parse.urljoin(response.url,link) # 拼接详情页网址
                yield scrapy.Request(url,callback=self.content) # 发送详情页请求
        yield scrapy.Request(next_page_url,callback=self.parse) # 发送下一页请求


    def content(self, response):
        '''文章内容页提取信息'''
        content = response.xpath('string(//div[@class='news_con'])').extract_first() # 详情信息
        title = response.xpath('//h1/text()').extract_first() # 公告标题
        rows = re.findall(r'\d+、.+(?=\r\n|\n)',content) # 数字开头,有换行符的每一行
        for row in rows:
            item = RiceItem() # 将字段信息的类RiceItem实例化为item
            item['title'] = title # 标题
            item['name'] = re.search('(?<=品名:).*?(?=[,,])',row).group() # 品名
            try:
                item['volumn'] = re.search('(?<=成交量:).*?(?=[,,])',row).group() # 成交量
            except:
                item['volumn'] = None
            try:
                item['price'] = re.search('(?<=成交单价:).*?(?=[,,])',row).group() # 成交单价
            except:
                item['price'] = None
            try:
                item['method'] = re.search('(?<=交易方式:).*?(?=[,,])',row).group() # 交易方式 
            except:
                item['method'] = None
            try:
                item['warehouse'] = re.search('(?<=港口/仓库:).*?(?=[;;。])',row).group() # 仓库
            except:
                item['warehouse'] = None
            yield item

原理就是start_urls请求目标网站第一页信息,

parse函数就是解析列表页,获取详情页网址,通过content函数请求详情页网址,获取文本并用正则表达式处理。

同时在parse中会获取下一页网址,不断迭代,直到最后一页。

代码每一行都有解释,有兴趣的可以看看。由于网站没有任何反爬措施,因此我连最基础的随机header请求头也没有写。

知识点:

xpath解析html,urllib.parse网址拼接,re正则表达式

爬取并存储数据

编写完成后,我们直接运行命令将数据保存为csv格式 ,这是scrapy自带功能。

scrapy crawl ricedata -o riceoutput.csv
                  

这里的ricedata就是最开始我们生成的爬虫名称,riceoutput.csv是我们想保存的文件名。

可以看到多线程飞速的爬取数据,完成后打开csv文件。

爬取了网站所有的粮食交易数据,由于他的文本数据有些不规范,有些行一些字段是没有数的。

以上就是使用scrapy最简单的举例,过程并不复杂,很多都是框架已经给你写好的。

网友举的这个例子让我想起还是审计助理的时候做的一个互联网理财公司,领导让我在他们官网上一个一个复制粘贴公告里的信息,最后,我就用vba写了个工具 ,秒速获取所有信息。

有时候,知识就是力量,不要折磨实习生,不要把还没进门未来的从业者吓跑了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多