栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

站点数据收集-Scrapy使用笔记

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

站点数据收集-Scrapy使用笔记

前言

网站数据收集方法有很多,比如最基础的requests,简单几行就可以获取网页信息。使用selenium模拟网页点击可以绕过很多反爬策略,编写思路也不同于其他的方法。用scrapy框架来做的话可以清楚地进行目标拆分,并利用内置的线程池可以非常高效地获取信息。

本文以scrapy为目标,总结基础的使用方法,以供后续复习。

配置

本地配置好python及pip后,使用pip install scrapy既可以安装scrapy。

基本使用 新建工程

scrapy在使用时,需要在主机命令行里scrapy startproject 创建一个项目,比如运行scrapy startproject example后生成example文件夹,内容如图所示。

添加目标网站

命令行也会提示进入example目录,并运行scrapy genspider来创建一个spider。比如运行scrapy genspider example_spider example.com,之后会在spiders文件夹下生成一个example_spider.py文件。爬虫的代码就需要写在这个文件内。

GET请求
import scrapy


class ExampleSpiderSpider(scrapy.Spider):
    name = 'example_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']

    def parse(self, response):
        pass
POST请求
import scrapy


class ExampleSpiderSpider(scrapy.Spider):
    name = 'example_spider'
    allowed_domains = ['example.com']
    urls = [
            'https://example.com/page/1/',
            'https://example.com/page/2/',
        ]
    
    def start_requests(self):
		for target in urls:
    	   #发送'Content-Type':'application/x-www-form-urlencoded'的请求
           yield scrapy.FormRequest(
            	url=url, 
            	formdata={'arg1':'xxx','arg2':'xxx'},
            	callback=self.parse, 
            	meta={'arg1':1,'arg2':2}
            )
           #发送'Content-Type':'application/json'的请求
           yield scrapy.Request(
            	url=url, 
            	method='POST',
            	body = json.dumps({'arg1':'xxx','arg2':'xxx'}),
            	headers = {'Content-Type':'application/json'},
            	callback=self.parse, 
            	meta={'arg1':1,'arg2':2}
            )
            
    def parse(self, response):
        pass

需要注意的是:

  1. name 是爬虫名字,即spidername,之后运行需要指定这个名字。
  2. allowed_domains 指定允许爬取的域名,也可以不要。
  3. start_urls指定需要爬取哪些网站,运行时会一个一个向这些网站发请求,并将响应传给parse函数。如果需要动态生成目标网站,可以删掉这个start_urls变量,并添加一个start_requests(self)成员函数(需要使用yield scrapy.Request(url = , callback=self.parse)作为返回值。爬虫运行时如果发现没有定义start_urls变量,则会调用这个函数。
  4. scrapy.Request用于发送GET请求。可以添加一个cb_kwargs参数,它接受一个字典,并可以在parse(self, response, **kwargs)中通过kwargs来获取这个字典,以实现自定义的参数传递。也可以使用meta参数,然后在parse里用response.meta获取传递的字典。
  5. scrapy.FormRequest用于发送POST请求,请求体放在formdata中,参数应当都是字符串类型。可以使用meta来进行参数传递(也可以用cb_kwargs? 没有测试)

这里对官方文档作以修改举例:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'https://quotes.toscrape.com/page/1/',
            'https://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse, cb_kwargs={'this_url':url})

    def parse(self, response, **kwargs):
        page = response.url.split("/")[-2]
        url = kwargs['this_url']
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')
启动爬取

在最外层的example目录下运行scrapy crawl ,即可开始爬取。

再以官网文档为例:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'https://quotes.toscrape.com/page/1/',
        'https://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

response.css来提取元素,其含义不言自明。也可以通过response.text获取文本信息。

这里的parse函数yield了一个字典,可以在运行时指定保存文件:scrapy crawl -O 来将其保存到文件中,方便后续处理。jl是jsonline即单行json,可以在python中使用简单的文件逐行遍历配合json来处理。其中-O表示覆盖输出文件,-o表示在输出文件后追加。可以添加-L ERROR来忽略运行时无关紧要的输出。

对公开API继续爬取时,jl有奇效。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030852.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号