代码优化之通用爬虫——scrapy爬取文章吧

上上篇博客记录了文章吧的文章爬取,作为一个学习爬虫的专业的程序猿,自然是离不开框架的

我们知道,我们爬取文章吧的文章,需要两步:

1,获取列表页的url,并构造该url的后续url爬取

2,在列表页获取详情页的url,进入详情页获取数据

问题来了,我们一般的scrapy项目,只能针对一个url发送request并获取response解析,我们怎么一边遍历列表页,一遍从详情页获取数据呢。

答案当然是,通用爬虫

我们已经知道了普通爬虫的创建方式,其实通用爬虫也相差不大

打开cmd终端,依旧是进入你需要的路径

执行以下命令

创建一个项目:

scrapy startproject wenzhangba 

进入该项目

cd wenzhangba

创建一个通用爬虫

scrapy genspider -t crawl article www.wenzhangba.com

加黑的是爬虫名,斜体是域名

然后用pycharm打开

先写爬虫

article.py:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from wenzhangba.items import WenzhangbaItem


class ArticleSpider(CrawlSpider):
    name = 'article'
    allowed_domains = ['www.wenzhangba.com']
    start_urls = ['http://www.wenzhangba.com/ganrengushi/list_20_1.html']

    rules = (
        #设置文章列表页爬取规则,
        #根据列表页链接设置爬取链接规则,
        #列表页无需提取数据,因此不需要callback方法
        #需要后面的列表页数据,允许跟进爬取
        Rule(LinkExtractor(allow=r'.+/ganrengushi/list_20_\d+.html'), follow=True),
        #设置文章详情页爬取规则
        # 根据详情页链接设置爬取链接规则,
        # 详情页需提取数据,因此需要callback方法
        # 不需要在详情页跟进爬取
        Rule(LinkExtractor(allow=r'.+/ganrengushi/\d+/\d+.html'), callback='parse_detail', follow=False),
    )

    def parse_detail(self, response):
        title = response.xpath("//div[@class='c_a_info']//h1/a/text()").get().strip()
        # print(title)
        date = response.xpath("//div[@class='a_tit']//span[@class='s1']/text()").get().strip()
        # print(date)
        #作者这项有一定的问题
        #1,该文章可能是个人写作投稿,class属性是s2
        #2,转载或声明来源,class属性是s5
        #3,前面是作者,后面是来源,且作者名字是可以跳转的链接,此时获取的作者只有“作者:”两个字,没有名字
        authors = response.xpath("//div[@class='a_tit']//span[@class='s2']/text()|"
                                "//div[@class='a_tit']//span[@class='s5']/text()").getall()
        if authors[0] == "作者:" :
            author = authors[1]
        else:
            author =authors[0]
        # print(author)
        #这里获取文章内容,不做去除标签等处理。
        #原因是爬下来的数据可以直接从数据库中拿出来放到网站
        #避免使用时前端需要再次处理的麻烦,我同学说的。
        content = response.xpath("//div[@class='a_detail']").get()
        item = WenzhangbaItem(title=title, date=date, author=author, content=content)
        yield item

一些介绍都放在代码的注释中了。不在多说

然后

items.py:

import scrapy


class WenzhangbaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    date = scrapy.Field()
    author = scrapy.Field()
    content = scrapy.Field()

piplines.py:

import pymysql

class WenzhangbaPipeline(object):
    def __init__(self, host, database, user, password, port):
        #构造数据库参数
        self.host = host
        self.database = database
        self.user = user
        self.password = password
        self.port = port

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=crawler.settings.get("MYSQL_HOST"),
            database=crawler.settings.get("MYSQL_DATABASE"),
            user=crawler.settings.get("MYSQL_USER"),
            password=crawler.settings.get("MYSQL_PASSWORD"),
            port=crawler.settings.get("MYSQL_PORT"),
        )

    def open_spider(self, spider):
        self.db = pymysql.connect(self.host,self.user,self.password,self.database,charset="utf8",port=self.port)
        self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        data = dict(item)
        sql = """
        insert into article(id, title, pub_time, author, content) values(null, %s, %s, %s, %s)
        """
        self.cursor.execute(sql,(item['title'], item['date'], item['author'], item['content']))
        self.db.commit()
        return item

    def close(self, spider):
        self.db.close()

设置settings.py

关闭协议:

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 6.1; Win64; x64) AppleWebKit/537.36 '
               '(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
}

设置并编写piplines配置

ITEM_PIPELINES = {
   'wenzhangba.pipelines.WenzhangbaPipeline': 300,
}
MYSQL_HOST = 'localhost'
MYSQL_DATABASE = 'wenzhangba'
MYSQL_PORT = 3306
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123'

最后,star.py:

from scrapy import cmdline

cmdline.execute("scrapy crawl article".split())

那么,代码就优化完成了,它会按照你给的规则抓取数据

看看数据库:

这里是一部分,因为是优化代码,数据用不到,所以只抓取了关键几项,没有上次获取的数据多。

努力学习。

以上

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,下面我来为你介绍一下如何使用Scrapy爬取豆瓣TOP250电影信息。 1. 安装Scrapy 首先,你需要安装Scrapy。如果你已经安装了Python,可以在命令行中使用以下命令安装Scrapy: ``` pip install Scrapy ``` 2. 创建Scrapy项目 接下来,我们需要创建一个Scrapy项目。在命令行中输入以下命令: ``` scrapy startproject douban_top250 ``` 这将会在当前目录下创建一个名为“douban_top250”的文件夹,其中包含了Scrapy项目的基本结构。 3. 编写爬虫代码 在“douban_top250/spiders”目录下创建一个名为“douban.py”的文件,并输入以下代码: ```python import scrapy class DoubanSpider(scrapy.Spider): name = 'douban' allowed_domains = ['movie.douban.com'] start_urls = ['https://movie.douban.com/top250'] def parse(self, response): for movie in response.xpath('//div[@class="hd"]'): yield { 'title': movie.xpath('.//span[@class="title"]/text()').extract_first(), 'rating': movie.xpath('../div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract_first(), 'link': movie.xpath('.//a/@href').extract_first(), } next_page = response.xpath('//span[@class="next"]/a/@href') if next_page: yield response.follow(next_page[0], self.parse) ``` 这段代码定义了一个名为“DoubanSpider”的类,用于爬取豆瓣电影TOP250的电影名称、评分和链接。在这个类中,我们使用了XPath选择器来定位页面中的元素。 4. 运行爬虫 在命令行中进入“douban_top250”文件夹,并输入以下命令来运行爬虫: ``` scrapy crawl douban -o douban_top250.csv ``` 这将会运行刚才编写的“DoubanSpider”爬虫,并将结果保存在名为“douban_top250.csv”的文件中。 至此,你已经学会了如何使用Scrapy爬取豆瓣TOP250电影信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值