如何用scrapy 去掉html标签提取不在标签内的文字

scrapy&笔记2
& &1.1 声明Items
& &Item使用简单的class定义语法以及&&对象来声明。例如:
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
1.2 创建item
&&& product = Product(name='Desktop PC', price=1000)
&&& print product
Product(name='Desktop PC', price=1000)
&1.3 获取字段的值
&&& product['name']
Desktop PC
&&& product.get('name')
Desktop PC
&&& product['price']
&&& product['last_updated']
Traceback (most recent call last):
KeyError: 'last_updated'
&&& product.get('last_updated', 'not set')
&&& product['lala'] # getting unknown field
Traceback (most recent call last):
KeyError: 'lala'
&&& product.get('lala', 'unknown field')
'unknown field'
&&& 'name' in product
# is name field populated?
&&& 'last_updated' in product
# is last_updated populated?
&&& 'last_updated' in product.fields
# is last_updated a declared field?
&&& 'lala' in product.fields
# is lala a declared field?
& 1.4 设置字段的值
&&& product['last_updated'] = 'today'
&&& product['last_updated']
&&& product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
KeyError: 'Product does not support field: lala'
获取所有获取到的值
您可以使用&&来获取所有的值:
&&& product.keys()
['price', 'name']
&&& product.items()
[('price', 1000), ('name', 'Desktop PC')]
&&& product2 = Product(product)
&&& print product2
Product(name='Desktop PC', price=1000)
&&& product3 = product2.copy()
&&& print product3
Product(name='Desktop PC', price=1000)
根据item创建字典(dict):
&&& dict(product) # create a dict from all populated values
{'price': 1000, 'name': 'Desktop PC'}
根据字典(dict)创建item:
&&& Product({'name': 'Laptop PC', 'price': 1500})
Product(price=1500, name='Laptop PC')
&&& Product({'name': 'Laptop PC', 'lala': 1500}) # warning: unknown field in dict
Traceback (most recent call last):
KeyError: 'Product does not support field: lala'
您可以通过继承原始的Item来扩展item(添加更多的字段或者修改某些字段的元数据)。
class DiscountedProduct(Product):
discount_percent = scrapy.Field(serializer=str)
discount_expiration_date = scrapy.Field()
&&Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。
换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。
对spider来说,爬取的循环类似下文:
以初始的URL初始化Request,并设置回调函数。
当该request下载完毕并返回时,将生成response,并作为参数传给该回调函数。
spider中初始的request是通过调用&&来获取的。&&读取&中的URL,
并以&&为回调函数生成&&。
在回调函数内分析返回的(网页)内容,返回&&对象或者&&或者一个包括二者的可迭代容器。
返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。
在回调函数内,您可以使用&&(您也可以使用BeautifulSoup,
lxml 或者您想用的任何解析器) 来分析网页内容,并根据分析的数据生成item。
最后,由spider返回的item将被存到数据库(由某些&&处理)或使用&&存入到文件中。
2.2 Spiders函数解释
classscrapy.spider.Spider
Spider是最简单的spider。每个其他的spider必须继承自该类(包括Scrapy自带的其他spider以及您自己编写的spider)。
Spider并没有提供什么特殊的功能。 其仅仅请求给定的start_urls/start_requests&,并根据返回的结果(resulting
responses)调用spider的&parse&方法。
定义spider名字的字符串(string)。spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。
不过您可以生成多个相同的spider实例(instance),这没有任何限制。
name是spider最重要的属性,而且是必须的。
如果该spider爬取单个网站(single domain),一个常见的做法是以该网站(domain)(加或不加&)来命名spider。
例如,如果spider爬取&&,该spider通常会被命名为mywebsite&。
allowed_domains
可选。包含了spider允许爬取的域名(domain)列表(list)。 当&&启用时,
域名不在列表中的URL不会被跟进。
start_urls
URL列表。当没有制定特定的URL时,spider将从该列表中开始进行爬取。 因此,第一个被获取到的页面的URL将是该列表之一。
后续的URL将会从获取到的数据中提取。
start_requests()
该方法必须返回一个可迭代对象(iterable)。该对象包含了spider用于爬取的第一个Request。
当spider启动爬取并且未制定URL时,该方法被调用。 当指定了URL时,&将被调用来创建Request对象。
该方法仅仅会被Scrapy调用一次,因此您可以将其实现为生成器。
该方法的默认实现是使用&&的url生成Request。
如果您想要修改最初爬取某个网站的Request对象,您可以重写(override)该方法。
例如,如果您需要在启动时以POST登录某个网站,你可以这么写:
def start_requests(self):
return [scrapy.FormRequest("/login",
formdata={'user': 'john', 'pass': 'secret'},
callback=self.logged_in)]
def logged_in(self, response):
# here you would extract links to follow and return Requests for
# each of them, with another callback
make_requests_from_url(url)
该方法接受一个URL并返回用于爬取的&&对象。
该方法在初始化request时被&调用,也被用于转化url为request。
默认未被复写(overridden)的情况下,该方法返回的Request对象中,&&作为回调函数,dont_filter参数也被设置为开启。
(详情参见&).
parse(response)
当response没有指定回调函数时,该方法是Scrapy处理下载的response的默认方法。
parse&负责处理response并返回处理的数据以及(/或)跟进的URL。&&对其他的Request的回调函数也有相同的要求。
该方法及其他的Request回调函数必须返回一个包含&&及(或)&&的可迭代的对象。
response&()
& 用于分析的response
log(message[,&level,&component])
使用&&方法记录(log)message。
log中自动带上该spider的&&属性。
更多数据请参见&&。
closed(reason)
当spider关闭时,该函数被调用。 该方法提供了一个替代调用signals.connect()来监听&信号的快捷方式。
2.4&CrawlSpider
classscrapy.contrib.spiders.CrawlSpider
爬取一般网站常用的spider。其定义了一些规则(rule)来提供跟进link的方便的机制。
也许该spider并不是完全适合您的特定网站或项目,但其对很多情况都使用。
因此您可以以其为起点,根据需求修改部分方法。当然您也可以实现自己的spider。
除了从Spider继承过来的(您必须提供的)属性外,其提供了一个新的属性:
一个包含一个(或多个)&&对象的集合(list)。
每个&&对爬取网站的动作定义了特定表现。
Rule对象在下边会介绍。 如果多个rule匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。
该spider也提供了一个可复写(overrideable)的方法:
parse_start_url(response)
当start_url的请求返回时,该方法被调用。
该方法分析最初的返回值并必须返回一个&对象或者
一个&&对象或者
一个可迭代的包含二者对象。
XMLFeedSpider
classscrapy.contrib.spiders.XMLFeedSpider
XMLFeedSpider被设计用于通过迭代各个节点来分析XML源(XML feed)。 迭代器可以从iternodes&,&xml&,&html&选择。
鉴于&xml&以及&html&迭代器需要先读取所有DOM再分析而引起的性能问题,
一般还是推荐使用&iternodes&。
不过使用&html&作为迭代器能有效应对错误的XML。
CSVFeedSpider
classscrapy.contrib.spiders.CSVFeedSpider
该spider除了其按行遍历而不是节点之外其他和XMLFeedSpider十分类似。
而其在每次迭代时调用的是&&。
2.6 &SitemapSpider
classscrapy.contrib.spiders.SitemapSpider
SitemapSpider使您爬取网站时可以通过&&来发现爬取的URL。
3 Selector
选择器API的完全参考详见&
31. 构造选择器(selectors)
Scrapy selector是以&文字(text)&或&&构造的&&实例。
其根据输入的类型自动选择最优的分析方法(XML vs HTML):
&&& from scrapy.selector import Selector
&&& from scrapy.http import HtmlResponse
以文字构造:
&&& body = '
Selector(text=body).xpath('//span/text()').extract()
以response构造:
&&& response = HtmlResponse(url='', body=body)
&&& Selector(response=response).xpath('//span/text()').extract()
3.2 使用选择器
我们将使用&Scrapy
shell&(提供交互测试)和位于Scrapy文档服务器的一个样例页面,来解释如何使用选择器:
这里是它的HTML源码:
Example website
'image1.html'Name:
My image 1 'image1_thumb.jpg'
'image2.html'Name:
My image 2 'image2_thumb.jpg'
'image3.html'Name:
My image 3 'image3_thumb.jpg'
'image4.html'Name:
My image 4 'image4_thumb.jpg'
'image5.html'Name:
My image 5 'image5_thumb.jpg'
首先, 我们打开shell:
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html
接着,当shell载入后,您将获得名为&response&的shell变量,其为响应的response,
并且在其response.selector&属性上绑定了一个selector。
因为我们处理的是HTML,选择器将自动使用HTML语法分析。
那么,通过查看&&该页面的源码,我们构建一个XPath来选择title标签内的文字:
&&& response.selector.xpath('//title/text()')
由于在response中使用XPath、CSS查询十分普遍,因此,Scrapy提供了两个实用的快捷方式:response.xpath()&及&response.css():
&&& response.xpath('//title/text()')
&&& response.css('title::text')
如你所见,&.xpath()&及&.css()&方法返回一个类&&的实例,
它是一个新选择器的列表。这个API可以用来快速的提取嵌套数据。
为了提取真实的原文数据,你需要调用&.extract()&方法如下:
&&& response.xpath('//title/text()').extract()
[u'Example website']
注意CSS选择器可以使用CSS3伪元素(pseudo-elements)来选择文字或者属性节点:
&&& response.css('title::text').extract()
[u'Example website']
现在我们将得到根URL(base URL)和一些图片链接:
&&& response.xpath('//base/@href').extract()
&&& response.css('base::attr(href)').extract()
&&& response.xpath('//a[contains(@href, "image")]/@href').extract()
[u'image1.html',
u'image2.html',
u'image3.html',
u'image4.html',
u'image5.html']
&&& response.css('a[href*=image]::attr(href)').extract()
[u'image1.html',
u'image2.html',
u'image3.html',
u'image4.html',
u'image5.html']
&&& response.xpath('//a[contains(@href, "image")]/img/@src').extract()
[u'image1_thumb.jpg',
u'image2_thumb.jpg',
u'image3_thumb.jpg',
u'image4_thumb.jpg',
u'image5_thumb.jpg']
&&& response.css('a[href*=image] img::attr(src)').extract()
[u'image1_thumb.jpg',
u'image2_thumb.jpg',
u'image3_thumb.jpg',
u'image4_thumb.jpg',
u'image5_thumb.jpg']
嵌套选择器(selectors)
选择器方法(&.xpath()&or&.css()&)返回相同类型的选择器列表,因此你也可以对这些选择器调用选择器方法。下面是一个例子:
&&& links = response.xpath('//a[contains(@href, "image")]')
&&& links.extract()
&&& for index, link in enumerate(links):
args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())
print 'Link number %d points to url %s and image %s' % args
Link number 0 points to url [u'image1.html'] and image [u'image1_thumb.jpg']
Link number 1 points to url [u'image2.html'] and image [u'image2_thumb.jpg']
Link number 2 points to url [u'image3.html'] and image [u'image3_thumb.jpg']
Link number 3 points to url [u'image4.html'] and image [u'image4_thumb.jpg']
Link number 4 points to url [u'image5.html'] and image [u'image5_thumb.jpg']
结合正则表达式使用选择器(selectors)
&也有一个&.re()&方法,用来通过正则表达式来提取数据。然而,不同于使用&.xpath()或者&.css()&方法,&.re()&方法返回unicode字符串的列表。所以你无法构造嵌套式的&.re()&调用。
下面是一个例子,从上面的&&中提取图像名字:
&&& response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
[u'My image 1',
u'My image 2',
u'My image 3',
u'My image 4',
u'My image 5'
4 移除命名空间。
在处理爬虫项目时,完全去掉命名空间而仅仅处理元素名字,写更多简单/实用的XPath会方便很多。你可以为此使用&&方法。
让我们来看一个例子,以Github博客的atom订阅来解释这个情况。
首先,我们使用想爬取的url来打开shell:
$ scrapy shell /blog.atom
一旦进入shell,我们可以尝试选择所有的&&对象,可以看到没有结果(因为Atom
XML命名空间混淆了这些节点):
&&& response.xpath("//link")
但一旦我们调用&&方法,所有的节点都可以直接通过他们的名字来访问:
&&& response.selector.remove_namespaces()
&&& response.xpath("//link")
如果你对为什么命名空间移除操作并不总是被调用,而需要手动调用有疑惑。这是因为存在如下两个原因,按照相关顺序如下:
移除命名空间需要迭代并修改文件的所有节点,而这对于Scrapy爬取的所有文档操作需要一定的性能消耗
会存在这样的情况,确实需要使用命名空间,但有些元素的名字与命名空间冲突。尽管这些情况非常少见。
5 Scrapy 终端
您可以使用
来启动Scrapy终端:
scrapy shell
是您要爬取的网页的地址。
Scrapy终端仅仅是一个普通的Python终端(或
)。其提供了一些额外的快捷方式。
可用的快捷命令(shortcut)
shelp() - 打印可用对象及快捷命令的帮助列表
fetch(request_or_url) -
根据给定的请求(request)或URL获取一个新的response,并更新相关的对象
view(response) - 在本机的浏览器打开给定的response。
其会在response的body中添加一个
,使得外部链接(例如图片及css)能正确显示。 注意,该操作会在本地创建一个临时文件,且该文件不会被自动删除。
可用的Scrapy对象
Scrapy终端根据下载的页面会自动创建一些方便使用的对象,例如
对象(对HTML及XML内容)。
这些对象有:
crawler - 当前
spider - 处理URL的spider。 对当前URL没有处理的Spider时则为一个
request - 最近获取到的页面的
对象。 您可以使用
修改该request。或者 使用 fetch
快捷方式来获取新的request。
response - 包含最近获取到的页面的
- 根据最近获取到的response构建的
settings - 当前的
终端会话(shell session)样例
下面给出一个典型的终端会话的例子。 在该例子中,我们首先爬取了
的页面,而后接着爬取
最后,我们修改了(Slashdot)的请求,将请求设置为POST并重新获取, 得到HTTP 405(不允许的方法)错误。
之后通过Ctrl-D(Unix)或Ctrl-Z(Windows)关闭会话。
需要注意的是,由于爬取的页面不是静态页,内容会随着时间而修改, 因此例子中提取到的数据可能与您尝试的结果不同。
该例子的唯一目的是让您熟悉Scrapy终端。
首先,我们启动终端:
scrapy shell 'http://scrapy.org' --nolog
接着该终端(使用Scrapy下载器(downloader))获取URL内容并打印可用的对象及快捷命令(注意到以
开头的行):
[s] Available Scrapy objects:
&200 http://scrapy.org&
&&& sel.xpath("//h2/text()").extract()[0]
u'Welcome to Scrapy'
&&& fetch("http://slashdot.org")
[s] Available Scrapy objects:
&200 http://slashdot.org&
\n\n\n\n\n
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。利用Python通过关键字抓取网页新闻
[问题点数:40分]
利用Python通过关键字抓取网页新闻
[问题点数:40分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。python中常用的写爬虫的库有urllib2、requests,对于大多数比较简单的场景或者以学习为目的,可以用这两个库实现。我之前写过的用urllib2+BeautifulSoup做的一个抓取百度音乐热门歌曲的例子,有兴趣可以看一下。
本文介绍用Scrapy抓取我在博客园的博客列表,只抓取博客名称、发布日期、阅读量和评论量这四个简单的字段,以求用较简单的示例说明Scrapy的最基本的用法。
环境配置说明
操作系统:Ubuntu 14.04.2 LTSPython:Python 2.7.6Scrapy:Scrapy 1.0.3
注意:Scrapy1.0的版本和之前的版本有些区别,有些类的命名空间改变了。
执行如下命令创建一个Scrapy项目
scrapy startproject scrapy_cnblogs
创建之后查看项目的目录结构如下:
scrapy_cnblogs
├── botcnblogs
  ├── __init__.py
  ├── items.py
#用于定义抓取内容的实体
  ├── pipelines.py
#处理抓取的item的管道
  ├── settings.py
#爬虫需要的配置参数在这里
└── spiders
   └── __init__.py
└── scrapy.cfg
#项目的配置文件,可以不去理会,默认即可
其中scrapy.cfg所在的目录为项目的根目录,此文件是项目的配置文件,项目建立后,此文件的内容可以不用理会。其内容如下:
[settings]
default = botcnblogs.settings
#url = http://localhost:6800/
project = botcnblogs
在items.py文件里定义在抓取网页内容中抽象出来的数据结构的定义,由于这里需要博客名称、发布日期、阅读量和评论量这四个字段,定义的Item结构如下:
from scrapy import Item,Field
#引入Item、Field
class BotcnblogsItem(Item):
# define the fields for your item here like:
title = Field()
publishDate = Field()
readCount = Field()
commentCount = Field() #评论数
在pipelines.py里对爬虫抓取到的信息(这里的信息是已经组织好的上面定义的Item对象)进行处理,官方介绍的典型的应用场景为:
清理HTML数据
验证爬取的数据(检查item包含某些字段)
查重(并丢弃)
将爬取结果保存到数据库中
它的定义也很简单,只需要实现process_item方法即可,此方法有两个参数,一个是item,即要处理的Item对象,另一个参数是spider,即爬虫。
另外还有open_spider和close_spider两个方法,分别是在爬虫启动和结束时的回调方法。
本例中处理很简单,只是将接收的Item对象写到一个json文件中,在__init__方法中以&w+&的方式打开或创建一个item.json的文件,然后把对象反序列化为字符串,写入到item.json文件中。代码如下:
# -*- coding: utf-8 -*-
import json
class BotcnblogsPipeline(object):
def __init__(self):
self.file = open("item.json", "w+")
def process_item(self, item, spider):
record = json.dumps(dict(item), ensure_ascii=False)+"\n"
#此处如果有中文的话,要加上ensure_ascii=False参数,否则可能出现乱码
self.file.write(record)
return item
def open_spider(self, spider):
def close_spider(self, spider):
self.file.close()
setting.py是爬虫的配置文件,配置爬虫的一些配置信息,这里用到的就是设置pipelines的ITEM_PIPELINES参数,此参数配置项目中启用的pipeline及其执行顺序,以字典的形式存在,{&pipeline&:执行顺序整数}
此例中的配置如下:
SPIDER_MODULES = ['botcnblogs.spiders']
NEWSPIDER_MODULE = 'botcnblogs.spiders'
ITEM_PIPELINES = {
'botcnblogs.pipelines.BotcnblogsPipeline': 1,
准备工作都做好了,爬虫呢,爬虫在哪里实现呢,我们看到项目中有个spiders目录,里面只有一个init.py文件,没错,爬虫文件需要自己创建,就在这个目录下,这里创建一个botspider.py的文件,对网页进行解析的工作就要在这里实现了,此例中定义的爬虫类继承自CrawlSpider类。
定义一个Spider需要如下几个变量和方法实现:
name:定义spider名字,这个名字应该是唯一的,在执行这个爬虫程序的时候,需要用到这个名字。
allowed_domains:允许爬取的域名列表,例如现在要爬取博客园,这里要写成
start_urls:爬虫最开始爬的入口地址列表。
rules:如果要爬取的页面不是单独一个或者几个页面,而是具有一定的规则可循的,例如爬取的博客有连续多页,就可以在这里设置,如果定义了rules,则需要自己定义爬虫规则(以正则表达式的方式),而且需要自定义回调函数。
代码说话:
#-*- coding:utf-8 -*-
__author__ = 'linuxfengzheng'
from scrapy.spiders import Spider, Rule
from scrapy.selector import Selector
from botcnblogs.items import BotcnblogsItem
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider
class botspider(CrawlSpider):
name = "cnblogsSpider"
#设置爬虫名称
allowed_domains = [""]
#设置允许的域名
start_urls = [
"/fengzheng/default.html?page=3",
#设置开始爬取页面
Rule(LinkExtractor(allow=('fengzheng/default.html\?page\=([\d]+)', ),),callback='parse_item',follow=True),
def parse_item(self, response):
sel = response.selector
posts = sel.xpath('//div[@id="mainContent"]/div/div[@class="day"]')
items = []
for p in posts:
#content = p.extract()
#self.file.write(content.encode("utf-8"))
item = BotcnblogsItem()
publishDate = p.xpath('div[@class="dayTitle"]/a/text()').extract_first()
item["publishDate"] = (publishDate is not None and [publishDate.encode("utf-8")] or [""])[0]
#self.file.write(title.encode("utf-8"))
title = p.xpath('div[@class="postTitle"]/a/text()').extract_first()
item["title"] = (title is not None and [title.encode("utf-8")] or [""])[0]
#re_first("posted @
10:32 风的姿态 阅读(\d+")
= p.xpath('div[@class="postDesc"]/text()').re_first(u"阅读\(\d+\)")
regReadCount = re.search(r"\d+", readcount)
if regReadCount is not None:
readcount = regReadCount.group()
item["readCount"] = (readcount is not None and [readcount.encode("utf-8")] or [0])[0]
commentcount
= p.xpath('div[@class="postDesc"]/text()').re_first(u"评论\(\d+\)")
regCommentCount = re.search(r"\d+", commentcount)
if regCommentCount is not None:
commentcount = regCommentCount.group()
item["commentCount"] = (commentcount is not None and [commentcount.encode("utf-8")] or [0])[0]
items.append(item)
return items
#self.file.close()
因为1.0版和之前的版本在包上有所改变,这里列出此例中所涉及的不同版本的区别
scrapy.spiders
scrapy.spider
CrawlSpider
scrapy.spiders
scrapy.contrib.spiders
LinkExtractor
scrapy.linkextractors
scrapy.contrib.linkextractors
scrapy.spiders
scrapy.contrib.spiders
爬虫思路:
首先进入到我的博客页面/fengzheng/,这是我的博客首页,以列表形式显示已经发布的博文,这是第一页,点击页面下面的下一页按钮,进入第二页,页面地址为/fengzheng/default.html?page=2,由此看出网站以page作为参数来表示页数,这样看来爬虫的规则就很简单了,&fengzheng/default.html\?page\=([\d]+),这个就是爬虫的规则,爬取default.html页面,page参数为数字的页面,这样无论有多少页都可以遍历到。当然,如果页面数量很少可以在start_urls列表中,将要爬取的页面都列出来,但是这样当博文数量增多就会出现问题,如下:
start_urls = [
"/fengzheng/default.html?page=1",
"/fengzheng/default.html?page=2",
"/fengzheng/default.html?page=3",
当爬取的网页具有规则定义的情况下,要继承CrawlSpider爬虫类,使用Spider就不行了,在规则定义(rules)时,如果要对爬取的网页进行处理,而不是简单的需要Url,这时,需要定义一个回调函数,在爬取到符合条件的网页时调用,并且设置follow=Ture,定义如下:
Rule(LinkExtractor(allow=('fengzheng/default.html\?page\=([\d]+)', ),),callback='parse_item',follow=True),
回调函数名称为parse_item,在parse_item方法中,就是真正要分析网页html,获取需要的内容的时候了。观察页面,查看需要的信息在什么位置,如图:  
之后,分析网页源码,分析出xpath
&用如下代码找到所有的class为day的div,每一个就是一个博文区域:
posts = sel.xpath('//div[@id="mainContent"]/div/div[@class="day"]')
 之后遍历这个集合,获取所需内容,其中注意一下几点:
&因为有中文内容,要对获取的内容进行encode("utf-8")编码
&由于评论数和阅读量混在一起,要对那个字符串再进行正则表达式提取 
&至此,简单的爬虫已经完成,接下来要运行这个爬虫,cd进入到爬虫项目所在的目录,执行以下命令:
scrapy crawl cnblogsSpider
会输出爬取过程信息
之后会看到,根目录中多了一个item.json文件,cat此文件内容,可以看到信息已经被提取出来:
阅读(...) 评论()}

我要回帖

更多关于 公式和文字不在一条线 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信