python scrapy 学习(二)IpSpider类

IpSpider类

上篇已经创建了第一个scrapy工程,新建了第一个爬取类IpSpider,用来从网站(或一组网站)中提取信息。它们必须子类化 scrapy.Spider并定义要生成的初始请求,可选择如何跟踪页面中的链接,以及如何解析下载的页面内容以提取数据。代码如下图所示:
在这里插入图片描述
IpSpider类定义的一些属性和方法:

  • name:识别spider。它在项目中必须是唯一的,也就是说,您不能为不同的Spiders设置相同的名称。
  • start_requests():必须返回Spider将开始爬行的可迭代请求(您可以返回请求列表或编写生成器函数)。后续请求将从这些初始请求中连续生成。
  • parse():将调用一个方法来处理为每个请求下载的响应。响应参数是TextResponse保存页面内容的实例,并具有处理它的其他有用方法。
    该parse()方法通常解析响应,将抽取的数据提取为dicts,并查找要遵循的新URL并Request从中创建新的request()。
运行周期

首先生成初始请求以爬网第一个URL,并指定要使用从这些请求下载的响应调用的回调函数。

第一个执行请求是通过调用 start_requests()(默认情况下)为在请求中作为回调函数的方法中Request指定的URL start_urls和parse方法生成的 方法获得的。

在回调函数中,您解析响应(网页)并返回带有提取的数据,Item对象, Request对象或这些对象的可迭代的dicts。这些请求还将包含一个回调(可能相同),然后由Scrapy下载,然后由指定的回调处理它们的响应。

在回调函数中,您通常使用选择器解析页面内容 (但您也可以使用BeautifulSoup,lxml或您喜欢的任何机制)并使用解析的数据生成项目。

最后,从spider返回的项目通常会持久保存到数据库(在某些项目管道中)或使用Feed导出写入文件。

start_requests 返回一个可迭代的请求,也可以用start_url替代,start_requests函数代码举例如下:

import scrapy

class IpSpider(scrapy.Spider):
    name = "myIp"
    allowed_domains = ["xicidaili.com"]
    # start_urls = [
    #     "https://www.xicidaili.com/nn/1",
    #     "https://www.xicidaili.com/nn/2"
    # ]

    def start_requests(self):
        urls = ["https://www.xicidaili.com/nn/1",
        "https://www.xicidaili.com/nn/2"]

        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)


    def parse(self, response):
        filename = response.url.split("/")[-1]
        print(filename)
        with open(filename, 'wb') as f:
            f.write(response.body)

执行结果是一样的。

提取数据

学习如何使用Scrapy提取数据的最佳方法是使用shell Scrapy shell尝试选择器。跑:

scrapy shell 'https://www.xicidaili.com/nn/1'

当从命令行运行Scrapy shell时,请记住始终将URL括在引号中,否则包含参数(即&字符)的url 将不起作用。在Windows上,请使用双引号:scrapy shell “https://www.xicidaili.com/nn/1

使用shell,您可以尝试使用CSS和响应对象选择元素(还可以使用xpath形式):

response.css('title')

结果为:
“[<Selector xpath=‘descendant-or-self::title’ data=’<title>国内高匿免费HTTP代理IP__第1页国内高匿’>]”

response.css('title::text').extract()

结果为:
[‘国内高匿免费HTTP代理IP__第1页国内高匿’]

取第一个元素:
response.css(‘title::text’).extract_first()
结果为:
‘国内高匿免费HTTP代理IP__第1页国内高匿’

使用.extract_first()避免IndexError和返回 None。

获取需要的ip、端口、协议等信息:

import scrapy

class IpSpider(scrapy.Spider):
    name = "myIp"
    allowed_domains = ["xicidaili.com"]
    start_urls = [
        "https://www.xicidaili.com/nn/1",
        "https://www.xicidaili.com/nn/2"
    ]

    def parse(self, response):
        trs = response.css('#ip_list tr')
        for tr in trs:
            td = tr.css('td')
            if len(td) == 0:
                continue
            yield {
                "ip":td.css('td::text')[0].extract(),
                "protocal":td.css('td::text')[5].extract(),
                "port":td.css('td::text')[1].extract(),
                "isGN":td.css('td::text')[4].extract()
            }
存储数据
scrapy crawl myIp -o myIp.json

在这里插入图片描述

json中存在中文乱码,可以在setting.py文件中修改默认的输出编码方式,只需要在setting.py中增加如下语句(默认似乎是没有指定的,所以要增加,如果默认有,就直接修改)

FEED_EXPORT_ENCODING = ‘utf-8’

新增下一页爬取
import scrapy

class IpSpider(scrapy.Spider):
    name = "myIp"
    allowed_domains = ["xicidaili.com"]
    start_urls = [
        "https://www.xicidaili.com/nn/1"
    ]

    def parse(self, response):
        trs = response.css('#ip_list tr')
        for tr in trs:
            td = tr.css('td')
            if len(td) == 0:
                continue
            yield {
                "ip":td.css('td::text')[0].extract(),
                "protocal":td.css('td::text')[5].extract(),
                "port":td.css('td::text')[1].extract(),
                "isGN":td.css('td::text')[4].extract()
            }

        next_page = response.css('.pagination a.next_page::attr("href")').extract_first()
        if next_page is not None and int(next_page.split('/')[-1]) < 10: #(暂限制爬取9页)
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值