爬虫入门之Scrapy框架实战(新浪百科豆瓣)(十二)

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 一 新浪新闻爬取1 爬取新浪新闻(全站爬取)项目搭建与开启scrapy startproject sinacd sinascrapy genspider mysina http://roll.

一 新浪新闻爬取

1 爬取新浪新闻(全站爬取)

项目搭建与开启

scrapy startproject sina
cd sina
scrapy genspider mysina http://roll.news.sina.com.cn/news/gnxw/gdxw1/index_2.shtml

2 项目setting配置

ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
   'sina.pipelines.SinaPipeline': 300,
}

3 启动文件start.py配置

import scrapy.cmdline
def main():
    # -o  ['json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle']
    scrapy.cmdline.execute(['scrapy','crawl','mysina'])

if __name__ == '__main__':
    main()

4 需求目标item配置

import scrapy

class SinaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    newsTitle = scrapy.Field()
    newsUrl = scrapy.Field()
    newsTime = scrapy.Field()
    content = scrapy.Field()

5 爬虫逻辑文件配置mysina.py

import scrapy
import requests
from lxml import etree
from sina import items
from scrapy.spiders import CrawlSpider,Rule  #CrawlSpiders:定义了一些规则跟进link
from scrapy.linkextractors import LinkExtractor  #提取链接

class MysinaSpider(CrawlSpider): #继承了CrawlSpider因此parse需要重命名防止冲突
    name = 'mysina'
    allowed_domains = ['sina.com.cn']
    start_urls = ['http://roll.news.sina.com.cn/news/gnxw/gdxw1/index_2.shtml']
    '''
    Rule参数:link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=identity
    LinkExtractor部分参数: allow=(), deny=(), allow_domains=(), deny_domains=(), restrict_xpaths=()

    allow=(正则)允许的, deny=(正则)不允许的
    callback=回调函数
    follow= 跟随如果为True就跟随
    '''
    rules = [Rule(LinkExtractor(allow=('index_(\d+).shtml')),callback='getParse',follow=True)]

    def getParse(self, response): #重命名逻辑方法
        newsList = response.xpath("//ul[@class='list_009']/li")
        for news in newsList:

            item = items.SinaItem() #对其进行实例化
            newsTitle = news.xpath('./a/text()')[0].extract()
            newsUrl = news.xpath('./a/@href')[0].extract()
            newsTime = news.xpath('./span/text()')[0].extract()
            content = self.getContent(newsUrl)

            item['newsTitle'] = newsTitle
            item['newsUrl'] = newsUrl
            item['newsTime'] = newsTime
            item['content'] = content
            yield item

    def getContent(self,url):
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36"
        }
        response = requests.get(url,headers=headers).content.decode('utf-8','ignore')   #content二进制
        mytree = etree.HTML(response)
        contentList = mytree.xpath("//div[@class='article']//text()")
        print(contentList)
        content = ''
        for c in contentList:
            #Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
            content += c.strip().replace('\n','')  #保证content为整片文章
        return content

方法二 :mysina.py也可采用scrapy创建请求

# -*- coding: utf-8 -*-
import scrapy
import requests
from lxml import etree
from sina import items

from scrapy.spiders import CrawlSpider,Rule  #CrawlSpiders:定义了一些规则跟进link
from scrapy.linkextractors import LinkExtractor  #提取链接

class MysinaSpider(CrawlSpider):
    name = 'mysina'
    allowed_domains = ['sina.com.cn']
    start_urls = ['http://roll.news.sina.com.cn/news/gnxw/gdxw1/index_2.shtml']
    rules = [Rule(LinkExtractor(allow=('index_(\d+).shtml')),callback='getParse',follow=True)]

    def getParse(self, response):

        newsList = response.xpath("//ul[@class='list_009']/li")
        for news in newsList:

            newsTitle = news.xpath('./a/text()')[0].extract()
            newsUrl = news.xpath('./a/@href')[0].extract()
            newsTime = news.xpath('./span/text()')[0].extract()

            #构造请求(修改为框架Request构造请求)
            request = scrapy.Request(newsUrl,callback=self.getMataContent) #回调为getMataContent
            #使用meta传参
            request.meta['newsTitle'] = newsTitle
            request.meta['newsUrl'] = newsUrl
            request.meta['newsTime'] = newsTime
            yield request

    def getMataContent(self,response):
        '''
        getMataContent接受来自request请求后的响应response
        '''
        contentList = response.xpath("//div[@class='article']//text()")
        content = ''
        for c in contentList:
            content += c.extract().strip()
        item = items.SinaItem()
        #response响应数据对应字段赋值给item
        item['newsTitle'] = response.meta['newsTitle']
        item['newsUrl'] = response.meta['newsUrl']
        item['newsTime'] = response.meta['newsTime']
        item['content'] = content
        yield item

6 管道存储pipelines.py

import pymysql

class SinaPipeline(object):
    def __init__(self):
        self.conn = None
        self.cursor = None

    def open_spider(self,spider):
        self.conn = pymysql.connect(host='111.230.169.xxx',user='root',password='xxx',database='sina', port=3306,charset='utf8') #创建连接
        self.cursor = self.conn.cursor()  #创建数据库游标

    def process_item(self, item, spider):
        sql = 'insert into sina_news(newsTitle,newsUrl,newsTime,content) VALUES (%r,%r,%r,%r)'%(item['newsTitle'], item['newsUrl'], item['newsTime'], item['content'])
        self.cursor.execute(sql)  #执行sql语句
        self.conn.commit()  #提交
        return item

    def close_spider(self,spider):
        self.cursor.close() #关闭
        self.conn.close()

方法二 : pipelines.py 补充快速创建sql语句

import pymysql

class DemoPipeline(object):

    def __init__(self):
        self.conn = None
        self.cur = None

    def open_spider(self, spider):
        self.conn = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123456',
            db='fate',
            charset='utf8')
        self.cur = self.conn.cursor()

    def process_item(self, item, spider):
        cols, values = zip(*item.items())  #zip打包返回两个参数
        sql = "INSERT INTO `%s` (%s) VALUES (%s)" % \
              (
                  'sina_news',
                  ','.join(cols),
                  ','.join(['%s'] * len(values))
               )
        self.cur.execute(sql, values) #执行sql语句并将values填充到%s
        self.conn.commit()
        return item

    def close_spider(self, spider):
        self.cur.close()
        self.conn.close()

二 百科资料的爬取

1 百科资料爬取

项目搭建与开启

scrapy startproject baike
cd baike
scrapy genspider mybaike baike.baidu.com/item/Python/407313

2 项目setting配置

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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
}
ITEM_PIPELINES = {
   'baike.pipelines.BaikePipeline': 300,
}

3 启动文件start.py配置

import scrapy.cmdline
def main():
    # -o  ['json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle']
    scrapy.cmdline.execute(['scrapy','crawl','mybaike'])

if __name__ == '__main__':
    main()

4 需求目标items配置

import scrapy

class BaikeItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    level1Title = scrapy.Field()
    level2Title = scrapy.Field()
    content = scrapy.Field()

5 爬虫逻辑文件配置mybaike.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor
from baike.items import BaikeItem

class MybaikeSpider(CrawlSpider):
    name = 'mybaike'
    allowed_domains = ['baike.baidu.com']
    start_urls = ['https://baike.baidu.com/item/Python/407313']

    rules = [Rule(LinkExtractor(allow=('item/(.*)')),callback='getParse',follow=True)]

    def getParse(self, response):
        level1Title = response.xpath("//dd[@class='lemmaWgt-lemmaTitle-title']/h1/text()")[0].extract()
        level2Title = response.xpath("//dd[@class='lemmaWgt-lemmaTitle-title']/h2/text()")
        if len(level2Title) != 0:
            level2Title = level2Title[0].extract()
        else:
            level2Title = '待编辑'
        contentList = response.xpath("//div[@class='lemma-summary']//text()")
        content = ''
        for c in contentList:
            content += c.extract()
        item = BaikeItem()
        item['level1Title'] = level1Title
        item['level2Title'] = level2Title
        item['content'] = content
        yield item

6 管道存储pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql

class BaikePipeline(object):
    def __init__(self):
        self.conn = None
        self.cousor = None

    def open_spider(self, spider):
        # 连接
        self.conn = pymysql.connect(host='111.230.169.107', user='root', password="20111673",
                                    database='baike', port=3306,
                                    charset='utf8')
        # 游标
        self.cousor = self.conn.cursor()

    def process_item(self, item, spider):

        cols, values = zip(*item.items())

        # `表名`
        sql = "INSERT INTO `%s`(%s) VALUES (%s)" % \
              ('baike', ','.join(cols), ','.join(['%s'] * len(values)))

        self.cousor.execute(sql, values)
        self.conn.commit()

        return item

    def close_spider(self, spider):
        self.cousor.close()
        self.conn.close()

三 豆瓣电影的爬取

1 豆瓣电影排行版

项目搭建与开启

scrapy startproject douban
cd douban
scrapy genspider mysina movie.douban.com/top250

2 项目setting配置

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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36"
}
ITEM_PIPELINES = {
   'douban.pipelines.DoubanPipeline': 300,
}

3 启动文件start.py配置

import scrapy.cmdline
def main():
    # -o  ['json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle']
    scrapy.cmdline.execute(['scrapy','crawl','mybaike'])

if __name__ == '__main__':
    main()

4 需求目标items配置

import scrapy

class DoubanItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    movieInfo = scrapy.Field()
    star = scrapy.Field()
    quote = scrapy.Field()

5 爬虫逻辑文件配置mydouban.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from douban.items import DoubanItem

class MydoubanSpider(scrapy.Spider):
    name = 'mydouban'
    url = ['https://movie.douban.com/top250']
    start_urls = {'https://movie.douban.com/top250'} #方法1

    '''#方法二
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
    }

    def start_requests(self):
        url = 'https://movie.douban.com/top250'
        yield Request(url, headers=self.headers)
    '''

    def parse(self, response):
        item = DoubanItem()
        movies = response.xpath('//ol[@class="grid_view"]/li')

        for movie in movies:
            item['name'] = movie.xpath(".//div[@class='pic']/a/img/@alt").extract()[0]
            item['movieInfo'] = movie.xpath(".//div[@class='info']/div[@class='bd']/p/text()").extract()[0].strip()
            item['star'] = movie.xpath(".//div[@class='info']/div[@class='bd']/div[@class='star']/span[2]/text()").extract()[0]
            item['quote'] = movie.xpath('.//div[@class="star"]/span/text()').re(r'(\d+)人评价')[0]
            yield item

        next_url = response.xpath('//span[@class="next"]/a/@href').extract() #获取下一页链接
        if next_url:
            next_url = 'https://movie.douban.com/top250' + next_url[0]
            yield Request(next_url,callback=self.parse)  #执行回调

6 管道存储pipelines.py

# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import pymysql

class DoubanPipeline(object):
    def __init__(self):
        self.conn = pymysql.connect(host='111.230.169.107', port=3306, user= 'root', passwd = 'xxx', database = 'douban',charset = 'utf8')
        self.cursor = self.conn.cursor()
        self.cursor.execute("truncate table Movie")   #此处设置每开启就清空
        self.conn.commit()

    def process_item(self, item, spider):
        try:
            self.cursor.execute("insert into Movie (name,movieInfo,star,quote) VALUES (%s,%s,%s,%s)",(item['name'], item['movieInfo'], item['star'], item['quote']))
            self.conn.commit()

        except pymysql.Error:
            print("Error%s,%s,%s,%s" % (item['name'], item['movieInfo'], item['star'], item['quote']))
        return item
    def close_spider(self, spider):
        self.cursor.close()
        self.conn.close()
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6天前
|
数据采集 存储 JSON
Python爬虫开发:BeautifulSoup、Scrapy入门
在现代网络开发中,网络爬虫是一个非常重要的工具。它可以自动化地从网页中提取数据,并且可以用于各种用途,如数据收集、信息聚合和内容监控等。在Python中,有多个库可以用于爬虫开发,其中BeautifulSoup和Scrapy是两个非常流行的选择。本篇文章将详细介绍这两个库,并提供一个综合详细的例子,展示如何使用它们来进行网页数据爬取。
|
11天前
|
数据采集 数据可视化 算法
【优秀python案例】基于Python的豆瓣电影TOP250爬虫与可视化设计与实现
本文设计并实现了一个基于Python的豆瓣电影TOP250爬虫与可视化系统,通过获取电影评分、评论并应用词云和饼图等可视化技术,为用户提供了电影评价的直观展示和深入分析。
【优秀python案例】基于Python的豆瓣电影TOP250爬虫与可视化设计与实现
|
24天前
|
数据采集 存储 XML
高级网页爬虫开发:Scrapy和BeautifulSoup的深度整合
高级网页爬虫开发:Scrapy和BeautifulSoup的深度整合
|
1天前
|
数据采集 存储 中间件
Python进行网络爬虫:Scrapy框架的实践
【8月更文挑战第17天】网络爬虫是自动化程序,用于从互联网收集信息。Python凭借其丰富的库和框架成为构建爬虫的首选语言。Scrapy作为一款流行的开源框架,简化了爬虫开发过程。本文介绍如何使用Python和Scrapy构建简单爬虫:首先安装Scrapy,接着创建新项目并定义爬虫,指定起始URL和解析逻辑。运行爬虫可将数据保存为JSON文件或存储到数据库。此外,Scrapy支持高级功能如中间件定制、分布式爬取、动态页面渲染等。在实践中需遵循最佳规范,如尊重robots.txt协议、合理设置爬取速度等。通过本文,读者将掌握Scrapy基础并了解如何高效地进行网络数据采集。
20 6
|
13天前
|
数据采集 XML 前端开发
Python爬虫实战:利用代理IP爬取百度翻译
Python 爬虫实战:利用代理 IP 爬取百度翻译
|
21天前
|
数据采集 API 开发者
🚀告别网络爬虫小白!urllib与requests联手,Python网络请求实战全攻略
【7月更文挑战第29天】在广阔的网络世界里,Python以其简洁的语法和强大的库支持成为网络爬虫开发的首选。本文聚焦于两大网络请求库——urllib和requests。urllib是Python内置库,虽API稍显复杂,却有助于理解HTTP本质。示例代码展示了如何使用`urlopen`函数发起GET请求并读取网页内容。相比之下,requests库则更加人性化,极大地简化了HTTP请求流程,使开发者能更专注于业务逻辑。
26 1
|
1月前
|
数据采集 Python
揭秘淘宝商品信息:Python爬虫技术入门与实战指南
Python爬虫用于获取淘宝商品详情,依赖`requests`和`beautifulsoup4`库。安装这两个库后,定义函数`get_taobao_product_details`,发送GET请求模拟浏览器,解析HTML获取标题和价格。注意选择器需随页面结构更新,遵守爬虫政策,控制请求频率,处理异常,且数据只能用于合法目的。
|
3月前
|
数据采集 存储 数据处理
Scrapy:Python网络爬虫框架的利器
在当今信息时代,网络数据已成为企业和个人获取信息的重要途径。而Python网络爬虫框架Scrapy则成为了网络爬虫工程师的必备工具。本文将介绍Scrapy的概念与实践,以及其在数据采集和处理过程中的应用。
43 1
|
3月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
20天前
|
数据采集 存储 NoSQL
Redis 与 Scrapy:无缝集成的分布式爬虫技术
Redis 与 Scrapy:无缝集成的分布式爬虫技术