python抓取动态网页(使用scrapy框架写爬虫时一般会在start_urls中定义的路径网页爬取 )
优采云 发布时间: 2021-11-02 19:13python抓取动态网页(使用scrapy框架写爬虫时一般会在start_urls中定义的路径网页爬取
)
在使用scrapy框架编写爬虫时,我们一般都会在start_urls中指定我们需要爬取的网页的URL进行爬取,但是如何让我们的爬虫像搜索引擎中使用的爬虫一样具有自动多网页爬取的功能呢?本文通过自动抓取个人csdn博客的所有文章标题、读者数量和创建时间进行简单说明。本文使用了两种不同的方法来实现这一点。
首先我们来分析一下cdsn中博客中文章的url。如图,我们可以发现不同的文章页面的url只是url末尾的一串数字不同,而在每篇文章文章下面@>都会有链接到上一个或下一个 文章。所以我们可以提取这个链接来实现网页的自动抓取。
在scrapy框架上写爬虫的整体流程和上一篇文章的流程是一样的。这里就不直接重复代码了。
项目.py
import scrapy
class CsdnItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
title=scrapy.Field()
time=scrapy.Field()
readtimes=scrapy.Field()
article_url=scrapy.Field()
pass
管道.py
import codecs
import json
from scrapy import signals
class CsdnPipeline(object):
def __init__(self):
self.file=codecs.open('data.json','w',encoding='utf-8')
def process_item(self, item, spider):
line=json.dumps(dict(item))+'\n'
self.file.write(line.decode("unicode_escape"))
return item
def spider_closed(self,spider):
self.file.close()
设置.py
# -*- coding: utf-8 -*-
# Scrapy settings for csdn project
#
# For simplicity, this file contains only the most important settings by
# default. All the other settings are documented here:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
#
BOT_NAME = 'csdn'
SPIDER_MODULES = ['csdn.spiders']
NEWSPIDER_MODULE = 'csdn.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'csdn (+http://www.yourdomain.com)'
USER_AGENT = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0'
ITEM_PIPELINES = {
'csdn.pipelines.CsdnPipeline':300,
}
DOWNLOAD_DELAY = 2
COOKIES_ENABLED=False
然后是最关键的爬虫部分。我们仍然使用的第一种方法是普通的 Spider。将要爬取的第一篇文章文章的地址放在start_urls中。爬取完这篇文章文章的基本信息,放入定义好的item,然后提取下一篇文章的连接地址,结合python中的yield,通过请求的功能和要求退货页面的内容在回调函数进行处理。具体代码如下:
蜘蛛1.py
#-*- coding:utf-8 -*-
from scrapy.spider import Spider
from scrapy.http import Request
from scrapy.selector import Selector
from csdn.items import CsdnItem
class csdnSpider(Spider):
name="csdn"
download_delay=1
allowed_domains=["blog.csdn.net"]
start_urls=[
"http://blog.csdn.net/u012286517/article/details/49556723"
]
def parse(self,response):
sel=Selector(response)
item=CsdnItem()
title=sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()
article_url = str(response.url)
time=sel.xpath('//div[@id="article_details"]/div[2]/div/span[@class="link_postdate"]/text()').extract()
readtimes=sel.xpath('//div[@id="article_details"]/div[2]/div/span[@class="link_view"]/text()').extract()
item['title']=[n.encode('utf-8').replace("\r\n","").strip() for n in title]
item['time']=[n.encode('utf-8') for n in time]
item['readtimes']=[n.encode('utf-8') for n in readtimes]
yield item
#get next url
urls=sel.xpath('//li[@class="next_article"]/a/@href').extract()
for url in urls:
print url
url="http://blog.csdn.net"+url
print url
yield Request(url,callback=self.parse)
第二种方法我们使用scrapy框架提供的CrawlSpider,它是Spider的派生类。普通蜘蛛只会抓取start_urls中定义的路径网页,但CrawlSpider定义了一些规则(rules),为后续链接提供便利的机制。可能蜘蛛并不完全适合你的特定网站 或项目,但它在很多情况下都会用到。所以你可以以它为起点,根据你的需要修改一些方法。当然你也可以实现自己的蜘蛛。
除了继承自Spider的属性(你必须提供)之外,它还提供了一个新的属性:
规则:
收录一个(或多个)规则对象的集合(列表)。每个规则定义了爬行 网站 的特定性能。下面将介绍 Rule 对象。如果多个规则匹配同一个链接,将根据它们在此属性中定义的顺序使用第一个。
蜘蛛还提供了一个可覆盖的方法:
parse_start_url(响应)
当 start_url 请求返回时,将调用此方法。此方法分析初始返回值,并且必须返回 Item 对象或 Request 对象或收录两者的可迭代对象。
具体实现代码如下:
在规则中,我们定义如何提取从被抓取网页的链接。在本例中,链接满足'/u012286517/article/details'的正则表达式。同时,restrict_xpath 用于限制仅从页面的特定部分提取要抓取的链接。
运行代码,我们得到如下结果,其中红线代表一块文章:
我们来看看爬取到的信息部分:其中,我们可以清楚地看到请求数和响应数为20,与博客中文章的数量一致。
下图是爬取返回的信息与csdn中的文章列表对比: