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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
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
如何将数据从MySQL同步到其他系统
【10月更文挑战第17天】如何将数据从MySQL同步到其他系统
186 0
|
18天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
127 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
18天前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
52 14
|
21天前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
48 9
|
2月前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
|
29天前
|
SQL 关系型数据库 MySQL
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
46 1
|
1月前
|
SQL 关系型数据库 MySQL
mysql数据误删后的数据回滚
【11月更文挑战第1天】本文介绍了四种恢复误删数据的方法:1. 使用事务回滚,通过 `pymysql` 库在 Python 中实现;2. 使用备份恢复,通过 `mysqldump` 命令备份和恢复数据;3. 使用二进制日志恢复,通过 `mysqlbinlog` 工具恢复特定位置的事件;4. 使用延迟复制从副本恢复,通过停止和重启从库复制来恢复数据。每种方法都有详细的步骤和示例代码。
159 2
|
26天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
76 6
|
2月前
|
数据采集 中间件 开发者
Scrapy爬虫框架-自定义中间件
Scrapy爬虫框架-自定义中间件
|
2月前
|
数据采集 中间件 Python
Scrapy爬虫框架-通过Cookies模拟自动登录
Scrapy爬虫框架-通过Cookies模拟自动登录