Scrapy实战

这篇文章详细描述了一个使用Scrapy框架编写的网络爬虫,它从desk.zol.com.cn网站抓取图片,通过XPath选择器解析HTML,屏蔽.exe链接,利用urljoin拼接URL,并通过Pipelines处理图片下载。重点介绍了请求处理、回调函数和图片下载路径设置的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码:

Spider

import scrapy
from urllib.parse import urljoin
from scrapy import Request

class JiaSpider(scrapy.Spider):
    name = "jia"
    allowed_domains = ["desk.zol.com.cn"]
    start_urls = ["https://desk.zol.com.cn/dongman/"]

    def parse(self, resp,**kwargs):
        #hrefs 为Selector形式,获取内容,用extract()
        hrefs = resp.xpath("//ul[@class='pic-list2  clearfix']/li/a/@href").extract()
        for href in hrefs:
            #屏蔽掉,exe结尾的
            if href.endswith('.exe'):#如果href以.exe结尾。就过滤掉
                continue
            else:

                # href = "https://desk.zol.com.cn/"+href
                # print(href)
                # clild_url = resp.urljoin(href)
                # print(clild_url)
                clild_url = urljoin(resp.url,href)
                #print(clild_url)
                #再次发送新的请求   所有的请求,必须经过引擎,交给调度器。然后反馈给引擎然后走下载器
                #再次发送请求,回来如果没有其他参数就会调用parse方法,回来就去执行,callback的函数·················
                yield Request(clild_url,callback=self.parse2)#回调函数。
    def parse2(self, resp, **kwargs):
        #详情页
        img = resp.xpath("//img[@id='bigImg']/@src").extract_first()
        print(img)
        yield {
            "src":img
        }

Pipelines:

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


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from scrapy.pipelines.images import ImagesPipeline#处理图片
from scrapy.pipelines.files import FilesPipeline#直接下载
from scrapy import Request
# class TupianPipeline:
#     def process_item(self, item, spider):
#         return item

class TupianPipeline(ImagesPipeline):

    def get_media_requests(self,item,info):
        src = item['src']
        yield Request(src,meta={"dizhi":src})
        # for s in src:
        #     #请求对象传值的最佳方案:meta
        #   yield Request(s,meta={"dizhi":src})#发送请求

    #scrapy 帮我们完成路径的处理  ,返回文件的路径(src)
    def file_path(self,request,response=None,info=None,*,item=None):
        dizhi = request.meta['dizhi']
        file_name = dizhi.split("/")[-1]
        return f"olie/guang/fengjun/guant/liejun/{file_name}.jpg"

    #数据的结束,收尾工作
    def item_completed(self,results,item,info):
        return item

Settings:

 

 Runner:

from scrapy.cmdline import execute

if __name__=="__main__":
    execute("scrapy crawl jia".split())

 将会加载图片

Spider中的思路

    def parse(self, resp,**kwargs):
        #hrefs 为Selector形式,获取内容,用extract()
        hrefs = resp.xpath("//ul[@class='pic-list2  clearfix']/li/a/@href").extract()
        for href in hrefs:
            #屏蔽掉,exe结尾的
            if href.endswith('.exe'):#如果href以.exe结尾。就过滤掉
                continue
            else:

                # href = "https://desk.zol.com.cn/"+href
                # print(href)
                # clild_url = resp.urljoin(href)
                # print(clild_url)
                clild_url = urljoin(resp.url,href)
                #print(clild_url)
                #再次发送新的请求   所有的请求,必须经过引擎,交给调度器。然后反馈给引擎然后走下载器
                #再次发送请求,回来如果没有其他参数就会调用parse方法,回来就去执行,callback的函数·················
                yield Request(clild_url,callback=self.parse2)#回调函数。

1.获得的内容,xpath将他解开,找到,东西后,extract()解析,因为直接获取的是Selector形式的

2.然后,得到的里面有.exe结尾的广告。将他屏蔽掉。

这里有三种,网址拼接方式。
传统的
1. # href = "https://desk.zol.com.cn/"+href
                # print(href)
这个是scrapy自带的
2.# clild_url = resp.urljoin(href)
       # print(clild_url)
这个是导入包
from urllib.parse import urljoin

3。clild_url = urljoin(resp.url,href)
 print(clild_url)

3.然后需要再次发送请求,第二个网址。这里会用到回调函数。

yield Request(clild_url,callback=self.parse2)#回调函数。

4.然后进入下一个爬虫:

    def parse2(self, resp, **kwargs):
        #详情页
        img = resp.xpath("//img[@id='bigImg']/@src").extract_first()
        print(img)
        yield {
            "src":img
        }

 然后字典返回数据到,管道。

这个得到的数据就是,图片的url

5.在Pipelines中会请求,图片的url然后,保存它

  for s in src:
             #请求对象传值的最佳方案:meta
           yield Request(s,meta={"dizhi":src})#发送请求
#scrapy 帮我们完成路径的处理  ,返回文件的路径(src)

6.

请求url得到图片

然后用 Split分割,得到最后一个,作为名字。

 #scrapy 帮我们完成路径的处理  ,返回文件的路径(src)
    def file_path(self,request,response=None,info=None,*,item=None):
        dizhi = request.meta['dizhi']
        file_name = dizhi.split("/")[-1]
        return f"olie/guang/fengjun/guant/liejun/{file_name}.jpg"

    #数据的结束,收尾工作
    def item_completed(self,results,item,info):
        return item

### Scrapy框架实战教程 Scrapy 是一个用于抓取网页并提取结构化数据的强大框架。以下是有关如何构建基于 Scrapy 的项目的详细说明。 #### 创建新的Scrapy项目 通过运行 `scrapy startproject` 命令可以初始化一个新的Scrapy项目[^2]。例如: ```bash scrapy startproject used_car_project ``` 此命令会生成标准的Scrapy项目结构,其中包括多个重要组件,如爬虫目录、中间件、管道以及配置文件等[^1]。 #### 项目结构详解 创建后的项目通常具有以下结构[^3]: - **myproject/**: 主要存储项目的核心代码。 - **__init__.py**: 初始化脚本。 - **items.py**: 定义数据项的数据模型。 - **middlewares.py**: 自定义请求或响应处理逻辑的地方。 - **pipelines.py**: 处理已抓取到的数据的位置。 - **settings.py**: 设置全局参数,比如下载延迟、并发数等。 - **spiders/**: 放置具体实现各个功能的爬虫类。 - **scrapy.cfg**: 配置整个项目的启动选项和其他元信息。 #### 编写第一个爬虫 在实际操作中,开发者需要进入 `spiders/` 文件夹下新建 Python 脚本来开发具体的爬虫程序。每一个独立的任务都可以封装成单独的一个 Spider 类实例。 对于二手车网站这样的场景来说,可能涉及多页翻阅或者复杂页面解析的情况,则可以通过继承官方提供的 CrawlSpider 或其他高级基类来简化工作流程。 另外,在某些情况下还需要自定义 Items 来保存所需字段的信息。下面是一个简单的例子展示如何声明这些属性[^4]: ```python import scrapy class UsedCarItem(scrapy.Item): name = scrapy.Field() price = scrapy.Field() mileage = scrapy.Field() ``` 以上片段展示了怎样利用 Field 方法为每辆车记录名称(name)、价格(price) 和行驶里程(mileage)。 最后一步就是设置好 Pipelines 将清洗过的资料储存至数据库或者其他形式的目标位置上去了! #### 示例代码总结 综合上述各部分内容之后得到完整的解决方案应该像这样子: ```python # Define the item structure. import scrapy class CarInfo(scrapy.Item): brand = scrapy.Field() # Brand of car (e.g., Toyota). model = scrapy.Field() # Model type (e.g., Corolla). year = scrapy.Field() # Year manufactured. # Implement spider logic here... from scrapy.spiders import Spider class ExampleSpider(Spider): name = 'example' allowed_domains = ['www.example.com'] start_urls = ['http://www.example.com/cars'] def parse(self, response): cars_listings = response.css('div.listing') for listing in cars_listings: yield { 'brand': listing.css('.make::text').get(), 'model': listing.css('.model::text').get(), 'year': int(listing.css('.year::text').re_first(r'\d{4}')) } next_page_url = response.css('a.next-page-link::attr(href)').extract_first() if next_page_url is not None: yield response.follow(next_page_url, self.parse) # Configure data processing pipeline inside pipelines.py file accordingly. def process_item(item, spider): ... return item ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值