使用scrapy爬取北京公交

环境

pycharm

安装好scrapy

创建一个scrapy项目

在pycharm中的命令行界面创建一个beijingbus的scrapy项目

D:\python\beibusTest>scrapy startproject beijingbus
#这里的D:\python\beibusTest>是我自己使用的路径,自己可以设置自己想要将项目保存的路径

切换到beijingbus目录,并使用genspider创建一个spider

D:\python\beibusTest>cd beijingbus

D:\python\beibusTest\beijingbus>scrapy genspider bei_bus beijing.8684.cn

使用pycharm打开我们创建的beijingbus项目

找到自己项目的路径(像我D:\python\beibusTest\beijingbus) 

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

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

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

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

beijingbus/settings.py:项目的设置文件,用来设置爬虫的默认信息,及相关功能的开启与否,如是否遵循robots协议,设置默认的hesder等

开始编写代码:

进入settings.py将ROBOTSTXT_OBEY的参数改为False,使爬虫不遵循Robots协议

ROBOTSTXT_OBEY = False

 将DEFAULT_REQUEST_HEADERS方法注释掉,添加User-Agent属性

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/87.0.4280.66 Safari/537.36'
}

 User-Agent的获取方法(打开浏览器,右键检查(或者f12)——Network——Headers)

(此操作是为了实现模拟浏览器访问的效果)

进入bei_bus.py文件:

1.先爬取一级网页

 代码:

进入bei_bus.py文件

#对自动生成的start_urls进行修改,改成如下
import scrapy

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):  #这里我只爬取了list1,可以自己选择加循环条件
            url = '{url}/list{page}'.format(url=self.start_urls, page=(page+1))  #是在构建一级网页的网址
            yield FormRequest(url, callback=self.parse_index)

    def parse(self, response):
        pass

在pycharm中的命令行界面(Terminal)执行'scrapy crawl bei_bus'可以实现一级网页的爬取:

2.再爬取二级网页

 

import scrapy
from scrapy import Spider, FormRequest, Request
from urllib.parse import urljoin

class BeiBusSpider(scrapy.Spider):
    name = 'bei_bus'
    allowed_domains = ['beijing.8684.cn']
    start_urls = 'http://beijing.8684.cn/'

    def start_requests(self):  # start_requests方法固定
        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, response):
        beijingbus = response.xpath('//div[@class="list clearfix"]/a//@href').extract()  #爬取二级网页
        for href in beijingbus:
            url2 = urljoin(self.start_urls, href)  #拼接二级网页
            yield Request(url2, callback=self.parse_detail)

    def parse_detail(self, response):
        pass

    def parse(self, response):
        pass
     

 在pycharm中的命令行界面(Terminal)执行'scrapy crawl bei_bus'可以实现二级网页的爬取:

3.再爬取详细信息

 

#这也是bei_bus.py中的完整代码

import scrapy
from scrapy import Spider, FormRequest, Request
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, response):
        #使用xpath寻找详细信息页面的url,具体用法可以搜索“xpath语法”
        beijingbus = response.xpath('//div[@class="list clearfix"]/a//@href').extract()  # extract()方法表示符合条件的所有文本
        for href in beijingbus:
            url2 = urljoin(self.start_urls, href)  # urljoin()方法拼接url
            # yield再次发起网页访问,callback后的方法用于回调函数,可以在回调函数中对网页进行处理
            yield Request(url2, callback=self.parse_detail)

# 下面是爬取详细页的代码:
    def parse_detail(self,response):
        bus_name = response.xpath('//div[@class="info"]/h1//text()').extract_first()  # extract_frist()方法用于返回符合条件的第一个数据
        bus_time = response.xpath('//div[@class="info"]/ul/li[1]//text()').extract_first()
        bus_type = response.xpath('//div[@class="info"]/ul/li[2]//text()').extract_first()
        #格式化数据
        bus_item = BeijingbusItem()
        for field in bus_item.fields:
            bus_item[field] = eval(field)  # eval() 函数用来执行一个字符串表达式,并返回表达式的值
        yield bus_item
        # pass

    def parse(self, response):
        pass

 在pycharm中的命令行界面(Terminal)执行'scrapy crawl bei_bus'可以实现详细页面的爬取:

(上图只是一部分) 

进入items.py文件,修改其中的class以格式化数据

import scrapy


class BeijingbusItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    bus_name = scrapy.Field()
    bus_type = scrapy.Field()
    bus_time = scrapy.Field()
    # pass

在数据库中创建数据表(shuju)并设置编码格式:

create table shuju(
bus_name varchar(100),
bus_time varchar(100),
bus_type varchar(100)
)CHARACTER SET utf8;

在settings.py中:

# 文末添加如下内容
DB_HOST = 'localhost'
DB_USER = 'root'
DB_PWD = '123456'
DB = 'test'  # 数据库 
DB_CHARSET = 'utf8'


# 将ITEM_PIPELINES 方法的注释去掉,并将其中的内容改为如下:
ITEM_PIPELINES = {
    'beijingbus.pipelines.BeijingbusPipeline': 300,  # 数字代表优先级,数字越小,优先级越高
}

在pipelines.py文件中:

from . import settings
import pymysql

#修改类为BeijingbusPipeline,添加初始化方法,将host,user,pwd,b,charset从settings中读取出来,并通过一个connect()方法建立与数据库的连接 
class BeijingbusPipeline:
    # 初始化方法
    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()  # 这里使用的是数据库对象self.conn中的cursor()方法
    
    # 实现process_item方法,用于完成向数据库中插入数据的操作
    def process_item(self, item, spider):
        sql = 'insert into shuju(bus_name,bus_time,bus_type) values ("%s","%s","%s")'%(item['bus_name'], item['bus_time'], item['bus_type'])
        # 执行SQL语句
        self.cursor.execute(sql)  # 使用execute方法执行SQL语句
        self.conn.commit()  # 提交到数据库执行
        return item

    # 用于关闭数据库的连接
    def close_spiders(self):
        self.conn.close()
        self.cursor.close()

 关于更多的python操作mysql数据库(cursor()游标讲解)可以参考下面这篇文章的讲解:

https://www.jb51.net/article/177865.htm

(转载别人的链接,如有侵权望作者告知,本人立即删除)

 最后在pycharm中的命令行界面(Terminal)执行'scrapy crawl bei_bus',再查看数据表:

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值