【数据采集与融合技术】第四次大作业

【数据采集与融合技术】第四次大作业

作业①

  • 要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;Scrapy+Xpath+MySQL数据库存储技术路线爬取当当网站图书数据

  • 候选网站:http://search.dangdang.com/?key=python&act=input

  • 关键词:学生可自由选择

  • 输出信息:MySQL的输出信息如下

    avatar

1)完成过程:

  • 大致思路:在spider中完成信息爬取及页面跳转的工作,将商品封装进item后交由pipeline进行数据库存储

1.通过浏览器检查网页html文档中的所需信息

  • 查看商品标签

    容易看出商品信息存储在li标签下,只需要对其中数据再做甄别即可

2.根据上一步结果爬取信息

  • 作者信息

  • 出版社信息
    出版社信息

  • 出版日期

  • 价格

  • 简介

  • 由于部分书籍不具备简介信息,使用前文方法无法准确区分,故改为在每个商品标签下逐个爬取

3.翻页处理

  • 观察可知page_index的值控制具体页数

page_limit = 2  # 页数上限
    for i in range(1, page_limit):
        # 生成对应页面url
        page_url = 'http://search.dangdang.com/?key=python&page_index='+str(page_limit)
        # 加入到start_urls中
        start_urls.append(page_url)

4.scrapy框架

  • spider
import scrapy
from scrapy.selector import Selector as selector
from ..items import Ex41Item


class MyspiderSpider(scrapy.Spider):
    name = 'myspider'
    allowed_domains = ['www.dangdang.com']
    start_urls = ['http://search.dangdang.com/?key=python']
    page_limit = 2  # 页数上限
    for i in range(1, page_limit):
        # 生成对应页面url
        page_url = 'http://search.dangdang.com/?key=python&page_index='+str(page_limit)
        # 加入到start_urls中
        start_urls.append(page_url)

    def parse(self, response):
        try:
            data = response.body.decode(response.encoding)
        except Exception as err:
            print(err)
            return
        s = selector(text=data)
        
        # 锁定商品li标签
        div = s.xpath('//div[@id="search_nature_rg"]')
        lis = div.xpath('.//li')
        
        # 爬取商品名
        title = s.xpath('//p[@class="name" and @name="title"]//a/@title').extract()
        # 爬取作者
        author = s.xpath('//p[@class="search_book_author"]/span[position()=1]/a[position()=1]/@title').extract()
        # 爬取出版商
        publisher = s.xpath('//p[@class="search_book_author"]/span[position()=3]/a[position()=1]/@title').extract()
        # 爬取出版日期
        date = s.xpath('//p[@class="search_book_author"]/span[position()=2]/text()').extract()
        # 爬取价格
        price = s.xpath('//span[@class="search_now_price"]/text()').extract()
        # 爬取简介
        detail = []
        for li in lis:
            d = li.xpath('.//p[@class="detail"]/text()').extract_first()
            detail.append(d if d else 'None')
            
        # 封装item
        for i in range(len(title)):
            item = Ex41Item()
            item['title'] = title[i]
            item['author'] = author[i]
            item['publisher'] = publisher[i]
            item['date'] = date[i].replace('/', '')
            item['price'] = price[i]
            item['detail'] = detail[i]
            yield item



  • item
import scrapy


class Ex41Item(scrapy.Item):
    title = scrapy.Field()
    author = scrapy.Field()
    publisher = scrapy.Field()
    date = scrapy.Field()
    price = scrapy.Field()
    detail = scrapy.Field()
    pass

  • pipeline
import sqlite3

class BookDB:
    def openDB(self):
        self.con = sqlite3.connect("books.db")
        self.cursor = self.con.cursor()
        self.no = 0
        try:  # 建表
            self.cursor.execute(
                "create table books (no varchar(5),title varchar(128),author varchar(64),publisher varchar(64),date varchar(16),price varchar(32),detail varchar(128),constraint pk_weather primary key (no))")
        except Exception as err:  # 表已存在则删除原有数据重新添加
            self.cursor.execute("delete from books")

    def closeDB(self):
        self.con.commit()
        self.con.close()

    def insert(self, item):
        try:  # 数据插入
            self.no += 1
            self.cursor.execute("insert into books (no,title,author,publisher,date,price,detail) values (?,?,?,?,?,?,?)",
                                (str(self.no),item['title'], item['author'], item['publisher'], item['date'], item['price'],
                                 item['detail']))
            print('书籍:', str(self.no), ' 保存成功!')
        except Exception as err:
            print(err)


class Ex41Pipeline:
    def __init__(self):  # 设置数据库对象
        self.db = BookDB()

    def open_spider(self, spider):  # 在spider开始运行时打开数据库
        self.db.openDB()

    def process_item(self, item, spider):  # 数据保存
        self.db.insert(item)
        return item

    def close_spider(self, spider):  # 在spider结束运行时关闭数据库
        self.db.closeDB()


5.结果展示

2)心得体会:

大部分内容与之前的作业相同,所以实现起来比较简单,需要仔细才能更准确爬取信息

作业②

  • 要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;使用scrapy框架+Xpath+MySQL数据库存储技术路线爬取外汇网站数据。

  • 候选网站:招商银行网:http://fx.cmbchina.com/hq/

  • 输出信息:MySQL数据库存储和输出格式

    Id Currency TSP CSP TBP CBP Time
    1 港币 86.60 86.60 86.26 85.65 15:36:30
    2......

1)完成过程

  • 大致思路:大致步骤与作业①相同。在spider中完成信息爬取工作,将信息封装进item后交由pipeline进行数据库存储。

1.通过浏览器检查网页html文档中的所需信息

  • 信息位于tr标签下

2.根据上一步结果爬取信息

  • 货币名

  • 其他信息

  • 数据清洗

3.scrapy框架

  • spider
import scrapy
from scrapy.selector import Selector as selector
from ..items import Ex42Item

class MyspiderSpider(scrapy.Spider):
    name = 'myspider'
    allowed_domains = ['fx.cmbchina.com/hq/']
    start_urls = ['http://fx.cmbchina.com/hq//']

    def parse(self, response):
        try:
            data = response.body.decode(response.encoding)
        except Exception as err:
            print(err)
            return
        s = selector(text=data)
        # 获得表格内逐行标签
        table = s.xpath('//table[@class="data"]')
        tr = table.xpath('.//tr')[1:]
        # 货币名称
        name = tr.xpath('.//td[position() = 1]/text()').extract()
        # 其他信息
        TSP = tr.xpath('.//td[position() = 4]/text()').extract()
        CSP = tr.xpath('.//td[position() = 5]/text()').extract()
        TBP = tr.xpath('.//td[position() = 6]/text()').extract()
        CBP = tr.xpath('.//td[position() = 7]/text()').extract()
        time = tr.xpath('.//td[position() = 8]/text()').extract()
        # 将清洗好的数据进行封装
        for i in range(len(tr)):
            item = Ex42Item()
            item['Currency'] = name[i].replace('\r\n', '').replace(' ', '')
            item['TSP'] = TSP[i].replace('\r\n', '').replace(' ', '')
            item['CSP'] = CSP[i].replace('\r\n', '').replace(' ', '')
            item['TBP'] = TBP[i].replace('\r\n', '').replace(' ', '')
            item['CBP'] = CBP[i].replace('\r\n', '').replace(' ', '')
            item['Time'] = time[i].replace('\r\n', '').replace(' ', '')
            yield item

  • item
import scrapy


class Ex42Item(scrapy.Item):
    Currency = scrapy.Field()
    TSP = scrapy.Field()
    CSP = scrapy.Field()
    TBP = scrapy.Field()
    CBP = scrapy.Field()
    Time = scrapy.Field()
    pass

  • pipeline
import sqlite3


class MoneyDB:
    def openDB(self):
        self.con = sqlite3.connect("money.db")
        self.cursor = self.con.cursor()
        try:  # 建表
            self.cursor.execute(
                "create table money (Currency varchar(20),TSP varchar(16),CSP varchar(16),TBP varchar(16),CBP varchar(16),Time varchar(16),constraint pk_weather primary key (Currency))")
        except Exception as err:  # 表已存在则删除原有数据重新添加
            self.cursor.execute("delete from money")

    def closeDB(self):
        self.con.commit()
        self.con.close()

    def insert(self, item):
        try:  # 数据插入
            self.cursor.execute("insert into money (Currency,TSP,CSP,TBP,CBP,Time) values (?,?,?,?,?,?)",
                                (item['Currency'], item['TSP'], item['CSP'], item['TBP'], item['CBP'],
                                 item['Time']))
            print(item['Currency'], ' 保存成功!')
        except Exception as err:
            print(err)


class Ex42Pipeline:
    def __init__(self):  # 设置数据库对象
        self.db = MoneyDB()

    def open_spider(self, spider):  # 在spider开始运行时打开数据库
        self.db.openDB()

    def process_item(self, item, spider):  # 数据保存
        self.db.insert(item)
        return item

    def close_spider(self, spider):  # 在spider结束运行时关闭数据库
        self.db.closeDB()

4.结果展示

2)心得体会:

通过本实验,进一步巩固了scrapy用法,还有对网页元素寻找更加熟练.

作业③

  • 要求:熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容;使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。

  • 候选网站:东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board

  • 输出信息:MySQL数据库存储和输出格式如下,表头应是英文命名例如:序号id,股票代码:bStockNo……,由同学们自行定义设计表头:

    序号 股票代码 股票名称 最新报价 涨跌幅 涨跌额 成交量 成交额 振幅 最高 最低 今开 昨收
    1 688093 N世华 28.47 62.22% 10.92 26.13万 7.6亿 22.34 32.0 28.08 30.2 17.55
    2......

1)完成过程:

  • 大致思路:等待网页加载完全后爬取信息,找到翻页及板块切换的标签,模拟点击来进行相应跳转

1.打开目标网页查看标签信息

  • 信息都在td标签内以固定顺序排列

2.尝试信息爬取

  • 当前页面信息爬取

3. 翻页与板块切换操作

4.结果展示

  • 控制台:
  • 数据库内容:

2)心得体会:

熟悉了selenium的使用,体验了模拟浏览器的方便之处,感受了selenium中find_element方法的多样与快捷。

代码

posted @ 2021-11-23 01:24  Poootato  阅读(10)  评论(0编辑  收藏  举报