
相信大家在浏览网页的经验中,都有看过利用分页的方式来呈现,将内容切成好几页,除了能够提升网页的执行效率外,还可以增加了使用者的体验。
在前面的Scrapy网页爬虫框架系列教学中,都分享了爬取单一网页的内容,这时候如果想要利用Scrapy网页爬虫框架来爬取多页的资料,该如何实作呢?这里就来延续[python]教你Scrapy框架汇出CSV档案方法提升资料处理效率-第七篇文章的教学内容,一起来学习这个技巧吧。实作的步骤包含:
Scrapy专案建立网页内容爬取方法(方法)Scrapy定位网页的下一页按钮Scrapy爬取多页的网页内容
一,Scrapy专案建立网页内容爬取方法(方法)
首先,来回顾一下目前在Scrapy网页爬虫(spiders / inside.py )所建立的parse()方法(Method),如下范例:
进口沙皮类InsideSpider (刮y的。蜘蛛):名称=“内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]def parse (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
以上范例第1132行为爬取INSIDE硬塞的网路趋势观察网站-AI新闻的单一网页,为了提升其中爬取逻辑的重用性(可重复使用),此处将其独立成一个新方法(Method),如下范例:
进口沙皮 刮y的类InsideSpider (scrapy 。蜘蛛):名称= “内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]def parse (self ,response ):产量从自我。刮(回应)#爬取网页内容def scrape (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
由于爬取逻辑被独立为一个新方法(方法),这时候在parse()方法(方法)中,则需使用“ yield from”关键字来进行呼叫,并导致网页的响应结果(response),来执行网页资料的爬取,如上范例第11行。
二,Scrapy定位网页的下一页按钮
开启INSIDE硬塞的网路趋势观察网站-AI新闻,往下可以看到页码的区域如下图:

如果想要利用Scrapy网页爬虫框架,继续爬取第二页的资料时,就需要取得下一页的网址,通常都会放在“下一页”按钮的href属性中。
在上图的「下一页」按钮点击快捷,选择「检查」,可以看到它的HTML原始码如下图:

接下来,返回Scrapy专案的spiders / inside.py档案,在parse()方法(Method)中,即可利用Scrapy框架的xpath()方法(Method),以“下一页”按钮的样式类别(class)来进行定位,如下范例第1415行:
进口沙皮 刮y的类InsideSpider (scrapy 。蜘蛛):名称= “内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]def parse (self ,response ):产量从自我。刮(回应)#爬取网页内容#定位「下一页」按钮元素next_page_url =响应。xpath (“ // a [@ class ='pagination_item pagination_item-next'] / @ href” )def scrape (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
三,Scrapy爬取多页的网页内容
在定位到INSIDE硬塞的网路趋势观察网站-AI新闻的「下一页」按钮后,接下来就要判断这个按钮是否存在,如果存在的话代表随后还有分页,需要继续往下爬取,反之,则停止,如下范例第1721行:
进口沙皮 刮y的类InsideSpider (scrapy 。蜘蛛):名称= “内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]def parse (self ,response ):产量从自我。刮(回应)#爬取网页内容#定位「下一页」按钮元素next_page_url =响应。xpath (“ // a [@ class ='pagination_item pagination_item-next'] / @ href” )如果next_page_url :url = next_page_url 。get ()#取得下一页的网址产量沙哑。请求(URL ,回调=自我。解析)#发送请求def scrape (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
其中,第21行的callback关键字参数(关键字参数)代表的意思,就是在Scrapy网页爬虫请求下一页的网址后,再重新执行parse()方法(方法),也就会获得下一页的响应结果(响应),爬取网页内容(第11行),并定位“下一页”按钮,判断如果存在的话,代表还有下一页,则获得下一页的网址,发送请求,此类类推,直到没有下一页为止。
以上就是将INSIDE硬塞的网路趋势观察网站-AI新闻的所有分页资料爬取下来的实作方法。当然,有时候并不想爬取那么多的资料,可能只需要特定页数的内容,来说前3页,该如何在Scrapy网页爬虫框架中实现呢?
这时候,就需要定义一个类别属性(Class Attribute),来计算当前执行的次数,如下范例第8行:
进口沙皮 刮y的类InsideSpider (scrapy 。蜘蛛):名称= “内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]count = 1 #执行次数def parse (self ,response ):产量从自我。刮(回应)#爬取网页内容#定位「下一页」按钮元素next_page_url =响应。xpath (“ // a [@ class ='pagination_item pagination_item-next'] / @ href” )如果next_page_url :url = next_page_url 。get ()#取得下一页的网址产量沙哑。请求(URL ,回调=自我。解析)#发送请求def scrape (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
由于在执行Scrapy网页爬虫时,一定会先执行一次,所以第8行的执行次数(计数)一级计数。
接下来,就可以在每一次一次请求下一页的网址前,将执行次数(计数)加1,判断如果在3次内,就发送请求,否则停止,如下范例第2225行:
进口沙皮 刮y的类InsideSpider (scrapy 。蜘蛛):名称= “内部”allowed_domains = [ 'www.inside.com.tw' ]start_urls = [ 'https://www.inside.com.tw/tag/ai' ]count = 1 #执行次数def parse (self ,response ):产量从自我。刮(回应)#爬取网页内容#定位「下一页」按钮元素next_page_url =响应。xpath (“ // a [@ class ='pagination_item pagination_item-next'] / @ href” )如果next_page_url :url = next_page_url 。get ()#取得下一页的网址InsideSpider 。计数+ = 1如果InsideSpider 。计数<= 3 :产量沙哑。请求(URL ,回调=自我。解析)#发送请求def scrape (self ,response ):#爬取文章标题post_titles =响应。xpath (“ // h3 [@ class ='post_title'] / a [@ class ='js-auto_break_title'] / text()”)。getall ()#爬取发布日期post_dates =响应。xpath (“ // li [@ class ='post_date'] / span / text()”)。getall ()#爬取作者post_authors =回应。xpath (“ // span [@ class ='post_author'] / a / text()”)。getall ()对于数据在拉链(post_titles ,post_dates ,post_authors ):NewsScraperItem = {“ post_title” :数据[ 0 ],“ post_date” :数据[ 1 ],“ post_author” :数据[ 2 ]}产生NewsScraperItem
最后,利用以下指令来执行Scrapy网页爬虫:
$ scrapy爬进里面
截取部分执行结果如下图:

以上就是爬取INSIDE硬塞的网路趋势观察网站-AI新闻的前3页内容,读者可依自己的需求来进行页数的调整。
四,小结
在实务上开发Python网页爬虫时,爬取分页资料是经常会碰到的情况,而此则利用一个实际的案例来让读者了解如何在Scrapy网页爬虫框架中来进行实作,对于想要爬取许多分页的读者,希望本文能够帮助您,如果有其他的想法或问题,欢迎在底下留言和我分享。
#Python爬虫#
举报/反馈
467

被折叠的 条评论
为什么被折叠?



