Python Scrapy爬虫教程

编程入门 行业动态 更新时间:2024-10-10 06:14:13

在之前我简单的实现了 Scrapy的基本内容。
存在两个问题需要解决。

先爬取详情页面,在根据页面url获取图片太费事了,要进行简化,一个项目就实现图片爬取。增量爬虫,网站数据更新,获取更新内容。

一般爬虫的逻辑是:给定起始页面,发起访问,分析页面包含的所有其他链接,然后将这些链接放入队列,再逐次访问这些队列,直至边界条件结束。为了针对列表页+详情页这种模式,需要对链接抽取(link extractor)的逻辑进行限定。我们先了解一下 crawlspider rules。

crawlspider rules的运行机制

request url的获取是Rule定位到的容器里,所有a标签里的href链接,比如用xpath定位。

rules = (Rule(LinkExtractor(restrict_xpaths=("//table[@class="tbspan"]/tr/td/b/a[2]")),callback='parse_item'),)

LinkExtractor 构造器各参数说明:blogs./xinglejun/p/10408630.html

容器下的所有a标签的链接全都会被获取到,并且侍自动发送请求,不用自己手动发送请求。响应页面是Rule请求的链接的页面内容,也就是你定位容器ul里的a标签的链接,然后你用鼠标点击该链接所看到的页面内容,在callback函数里提取数据也是在这个页面里提取,parse_item(self,response),这个函数的response对象就是这个页面内容,千万不要搞错对象了。

follow,follow就是跟进的意思,如果follow=True,那么,在你获取到的响应页面里,所以符合Rule规则的href链接都会被获取到,而且它还会自动跟进,进入到获取到的链接响应页面,在该页面又一次匹配Rule规则,看看有没有符合的,如果有又继续跟进,一直到匹配不到规则为止。
详细的解释看:blog.csdn.net/joe8910/article/details/85159059。

rules = (Rule(LinkExtractor(restrict_xpaths=("//table[@class="tbspan"]/tr/td/b/a[2]")),callback='parse_item'),Rule(LinkExtractor(allow=r'list_4_\d+\.html'), callback='parse_item', follow=True),
)

一条是获取响应页面规则,一条是获取翻页链接规则。我们运行一下试试。

class ChinesemedicineSpider(CrawlSpider):name = 'chinesemedicine'#allowed_domains = ['yzs.satcm.gov.']start_urls = ['ygdy8.net/html/gndy/china/index.html']rules = (Rule(LinkExtractor(restrict_xpaths=("//table[@class='tbspan']/tr/td/b/a[2]")),callback='parse_item'),Rule(LinkExtractor(allow=r'list_4_\d+\.html'), follow=True),)def parse_item(self, response):item = {}print('page: %s' % response.url)


这个是一个方法实现,但我们不选择这个,而选择另一个办法实现。

class ChinesemedicineSpider(CrawlSpider):name = 'chinesemedicine'#allowed_domains = ['yzs.satcm.gov.']start_urls = ['ygdy8.net/html/gndy/china/index.html']rules = (Rule(LinkExtractor(allow=r'list_4_\d+\.html'),callback='parse_item', follow=True),)def parse_item(self, response):detail_url_list = ['ygdy8.net' + el for el in  response.xpath( "//table[@class='tbspan']/tr/td/b/a[2]/@href").extract()]        for url in detail_url_list:yield scrapy.Request(url=url, callback=self.parse_detail)def parse_detail(self,response):print('url :'+response.xpath('//p/img[1]/@src').extract_first())

他与上一个类似,但区别在于使用 parse_detail(self,response)来解析详情页面,这个好处在于我们后面在增量查询时,减少建立连接数。

增量式爬取工作

在发送请求之前判断这个URL之前是不是爬取过在解析内容之后判断该内容之前是否爬取过在写入存储介质时判断内容是不是在该介质中

去重的方法
将爬取过程中产生的URL进行存储,存入到redis中的set中,当下次再爬取的时候,对在存储的URL中的set中进行判断,如果URL存在则不发起请求,否则就发起请求。
对爬取到的网站内容进行唯一的标识,然后将该唯一标识存储到redis的set中,当下次再爬取数据的时候,在进行持久化存储之前,要判断该数据的唯一标识在不在redis中的set中,如果在,则不在进行存储,否则就存储该内容。
一般而言,对url的去重是增量爬虫的关键,所以必须去重。爬虫爬取的是大规模的相同类型网站,对于每一个爬虫的结果还会汇总,所以对于内容解析去重并不一定要做,我们可以在汇总后写入存储介质时再去重,但对于汇总时对传输有要求时,还是解析内容去重。

Redis 安装

Window 下安装
下载地址:github./tporadowski/redis/releases。

Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 redis。
打开一个 cmd 窗口 使用 cd 命令切换目录到 C:\redis 运行:

redis-server.exe redis.windows.conf

如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。

这时候另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端了。

切换到 redis 目录下运行:

redis-cli.exe -h 127.0.0.1 -p 6379

这样就可以在shell中操作redis了。

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
我们把爬取过的url添加到Redis的set中,这样就可以通过判断url是否在set中判断url是否爬取过。
具体代码如下:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from redis import Redisclass ChinesemedicineSpider(CrawlSpider):name = 'chinesemedicine'start_urls = ['ygdy8.net/html/gndy/china/index.html']rules = (Rule(LinkExtractor(allow=r'list_4_\d+\.html'),callback='parse_item', follow=True),)def parse_item(self, response):conn = Redis(host='127.0.0.1', port=6379)detail_url_list = ['ygdy8.net' + el for el in  response.xpath("//table[@class='tbspan']/tr/td/b/a[2]/@href").extract()]for url in detail_url_list:# ex == 1:set中没有存储urlprint("from :"+ url)ex = conn.sadd('movies_url',url)if ex == 1:yield scrapy.Request(url=url, callback=self.parse_detail)else:print('已爬取过')def parse_detail(self,response):#item = Scrapy2Item()print('url :'+response.xpath('//p/img[1]/@src').extract_first())#yield item

这样我们实现了简单的增量爬虫。

更多推荐

爬虫,教程,Python,Scrapy

本文发布于:2023-05-28 00:49:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/308277.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:爬虫   教程   Python   Scrapy

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!