五十四、使用Scrapy爬取北京公交信息(将爬取的数据存入Mysql)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 五十四、使用Scrapy爬取北京公交信息(将爬取的数据存入Mysql)

环境准备:


python3.7


Pycharm


Scrapy框架


       注:全部源代码会在文章最后给出


理论概述:


什么是Scrapy框架?


       Scrapy是一个快速、高层次、轻量级的屏幕抓取和web抓取的python爬虫框架


Scrapy的用途?


       Scrapy用途非常广泛,主要用于抓取特定web站点的信息并从中提取特定结构的数据,除此之外,还可用于数据挖掘、监测、自动化测试、信息处理和历史片段(历史记录)打包等


目标网址:


18.png


环境搭建:


一、安装Scrapy


安装Scrapy的方式有两种:


A、使用Anaconda进行安装


B、使用pip安装


       注:使用Anaconda安装Scrapy需要已经安装好Anaconda才能继续安装Scrapy,使用pip安装需要先下载Twisted插件,直接安装scrapy是会报错的,笔者推荐使用Anaconda进行安装


       1、使用Anaconda安装:


conda install scrapy

19.png


        2、使用pip安装:


               A:安装Twisted:


windows 64位及python3.7版本https://download.csdn.net/download/m0_54925305/59579598?spm=1001.2014.3001.5503

https://download.csdn.net/download/m0_54925305/59579598?spm=1001.2014.3001.5503


其余版本下载链接https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted


进入终端:


pip install Twisted文件名   再 pip install scrapy


安装成功后的效果,终端输入scrapy:


20.png


二、创建 beijingbus 的scrapy项目


       1、进入pycharm的终端创建scrapy项目


21.png


        2、进入创建的beijingbus目录


22.png


       3、创建一个spider


23.png


三、搭建scrapy项目


项目主体架构:


24.png


功能描述:


beijingbus/spiders/:放置spider代码的目录,用于编写用户自定义的爬虫


beijingbus/items.py:项目中的item文件,用于定义用户要抓取的字段


beijingbus/middlewares.py:主要是对功能的拓展,用于用户添加一些自定义的功能


beijingbus/pipelines.py:管道文件,当spider抓取到内容(item)以后,会被送到这里,这些信息在这里会被清洗,去重,保存到数据库等


beijingbus/settings.py:项目的设置文件,配置的默认功能在这里存放


       1、进入settings.py将ROBOTSTXT_OBEY的参数改为False,目的是使其不遵守Robots协议


25.png


       2、将DEFAULT_REQUEST_HEADERS方法注释掉,并在其中添加User-Agent属性,代码如下


26.png

27.png


       注:此操作的功能是使爬虫实现模拟浏览器访问的效果


       3、进入bei_bus.py文件,对start_urls进行修改,代码如下图


28.png


       4、新建一个start_requests()方法(此方法名固定),获得并构建一级网页URL,代码如下


def start_requests(self):
        #这里的循环可以根据实际情况自行修改,这里不想全部爬取,只要list1下的就可以,故循环执行一次
        #start_requests()方法使用 format 拼接 URL,并用 yield 再次发起网页访问, callback 后的方法为回调函数,可以在回调函数中对网页进行处理。
        for page in range(1):
            url = '{url}/list{page}'.format(url=self.start_urls, page=(page + 1))
            yield FormRequest(url, callback=self.parse_index)

       5、在pycharm中的命令行界面执行 "scrapy crawl bei_bus" 爬取一级网页,效果如下进入beijingbus/目录下执行 "scrapy crawl bei_bus"命令

29.png


       注:scrapy框架爬虫开始执行


一级网页效果:


30.png


        6、 爬取二级网页


 

def parse_index(self, reponse):
        beijing = reponse.xpath('//div[@class="list clearfix"]/a//@href').extract()
        for c in beijing:
            url3 = urljoin(self.start_urls, c)
            yield Request(url3, callback=self.parse_detail)

       进入命令行界面执行 "scrapy crawl bei_bus" 爬取二级网页,效果如图


31.png


       注:在parse_index()方法中,使用Xpath寻找详细信息页面的URL,并对网址进行拼接,之后对二级网页发起请求,并返回回调函数parse_detail()


       7、爬取页面详细信息


def parse_detail(self, response):
        #这里只爬取这些字段,可以自行添加
        a = response.xpath('//h1[@class="title"]/text()').extract_first()
        b = response.xpath('//a[@class="category"]/text()').extract_first()
        c = response.xpath('//ul[@class="bus-desc"]/li[1]/text()').extract_first()
        item = BeijingbusItem()
        for field in item.fields:
            item[field] = eval(field)
        yield item

32.png


       8、详细信息页面效果

33.png


       注:这将会爬取到list1标签内所有路信息,其中包括公交路线,市区普线,运行时间这些字段,其余字段可以自行添加。


       9、将爬取的内容存入Mysql


A、在 MySQL 的 studb 数据库中创建一个 businfo 表:


create table businfo(
  a varchar(1000),
  b varchar(1000),
  c varchar(1000));

B、在 settings.py 文件末尾添加如下参数:


DB_HOST = 'localhost'
DB_USER = 'root'
DB_PWD = 'dang'
DB_CHARSET='UTF8'
DB = 'studb'

C、在 pipelines.py 文件中,修改 class 名称为 MySQL Pipeline,添加初始化方法,将 host、user、password、db、charset 从 settings 中读取出来,并通过添加一个connect()方法建立与数据库的连接,代码如下。


import pymysql
from itemadapter import ItemAdapter
from beijingbus import settings
class MysqlPipeline(object):
    def __init__(self):
        self.host = settings.DB_HOST
        self.user = settings.DB_USER
        self.pwd = settings.DB_PWD
        self.db = settings.DB
        self.charset = settings.DB_CHARSET
        self.connect()
    def connect(self):
        self.conn = pymysql.connect(host=self.host, user=self.user, password=self.pwd, db=self.db, charset=self.charset)
        self.cursor = self.conn.cursor()
    def process_item(self, item, spider):
        sql = 'INSERT INTO businfo (a,b,c)VALUES("%s","%s","%s")' % (item['a'], item['b'], item['c'])
        self.cursor.execute(sql)
        self.conn.commit()
        return item
    def close_spider(self, spider):
        self.conn.close()
        self.cursor.close()

       注:close_spider()方法,用于关闭 MySQL 数据库连接,process_item()方法,用于完成向数据库中插入数据的操作


D、在 settings.py 中将 ITEM_PIPELINES 方法的注释去掉,并将其中的内容 改为“'beibus.pipelines.MysqlPipeline':300”,后面的数字代表优先级,数字越小, 优先级越高,代码如下:


ITEM_PIPELINES = {
    'beijingbus.pipelines.MysqlPipeline': 300
}

       10、在 PyCharm 软件左下角单击“Terminal”标签,进入命令行界面,在其中执行 “scrapy crawl bei_bus”命令,启动爬虫项目,查看数据库


34.png


程序完整源代码


bei_bus.py:


import scrapy
from scrapy import Spider, Request, FormRequest
from urllib.parse import urljoin
from ..items import BeijingbusItem
class BeiBusSpider(scrapy.Spider):
    name = 'bei_bus'
    allowed_domains = ['beijing.8684.cn']
    start_urls = 'http://beijing.8684.cn/'
    def start_requests(self):
        for page in range(1):
            url = '{url}/list{page}'.format(url=self.start_urls, page=(page + 1))
            yield FormRequest(url, callback=self.parse_index)
    def parse_index(self, reponse):
        beijing = reponse.xpath('//div[@class="list clearfix"]/a//@href').extract()
        for c in beijing:
            urls = urljoin(self.start_urls, c)
            yield Request(urls, callback=self.parse_detail)
    def parse_detail(self, response):
        a = response.xpath('//h1[@class="title"]/text()').extract_first()
        b = response.xpath('//a[@class="category"]/text()').extract_first()
        c = response.xpath('//ul[@class="bus-desc"]/li[1]/text()').extract_first()
        # 格式化数据
        ab = BeijingbusItem()
        for field in ab.fields:
            ab[field] = eval(field)
        yield ab
    def parse(self, response):
        pass

       注:当添加其他字段的爬取时也要进行格式化数据,即在items.py中进行格式化,如下


items.py:


import scrapy
#格式化数据
class BeijingbusItem(scrapy.Item):
    a = scrapy.Field()
    b = scrapy.Field()
    c = scrapy.Field()

pipelines.py:


import pymysql
from itemadapter import ItemAdapter
from beijingbus import settings
class MysqlPipeline(object):
    def __init__(self):
        self.host = settings.DB_HOST
        self.user = settings.DB_USER
        self.pwd = settings.DB_PWD
        self.db = settings.DB
        self.charset = settings.DB_CHARSET
        self.connect()
    def connect(self):
        self.conn = pymysql.connect(host=self.host, user=self.user, password=self.pwd, db=self.db, charset=self.charset)
        self.cursor = self.conn.cursor()
    def process_item(self, item, spider):
        sql = 'INSERT INTO businfo (a,b,c)VALUES("%s","%s","%s")' % (item['a'], item['b'], item['c'])
        self.cursor.execute(sql)
        self.conn.commit()
        return item
    def close_spider(self, spider):
        self.conn.close()
        self.cursor.close()

settings.py:


BOT_NAME = 'beijingbus'
SPIDER_MODULES = ['beijingbus.spiders']
NEWSPIDER_MODULE = 'beijingbus.spiders'
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
}
ITEM_PIPELINES = {
    'beijingbus.pipelines.MysqlPipeline': 300
}
DB_HOST = 'localhost'
DB_USER = 'root'
DB_PWD = 'dang'
DB_CHARSET = 'UTF8'
DB = 'studb'

程序框架主体逻辑:

       1、修改settings.py将ROBOTSTXT_OBEY的参数改为False


       2、修改settings.py添加User-Agent属性


       3、编写bei_bus.py


       4、编写items.py以格式化数据


       5、新建数据库表


       6、编写MysqlPipeline.py


       7、运行bei_bus爬虫项目


使用Scrapy爬取北京公交信息完成


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
关系型数据库 MySQL Java
【MySQL+java+jpa】MySQL数据返回项目的感悟
【MySQL+java+jpa】MySQL数据返回项目的感悟
47 1
|
2月前
|
安全 关系型数据库 MySQL
如何将数据从MySQL同步到其他系统
【10月更文挑战第17天】如何将数据从MySQL同步到其他系统
253 0
|
2月前
|
SQL 前端开发 关系型数据库
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
60 0
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
|
2月前
|
关系型数据库 MySQL 数据库
mysql 里创建表并插入数据
【10月更文挑战第5天】
145 1
|
2月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
54 3
|
6天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
34 6
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
141 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
18天前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
|
23天前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据
|
1月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
62 14