nfcpy从NFC标签中检索URL.但是我该如何打开链接



我想要什么:

我想让我的树莓派充当一个NFC阅读器,可以从NFC标签触发URL记录。

我的设置是一个复盆子Pi与PN532 NFC HAT和nfcpy。我正在使用示例tagtool.py,现在我可以扫描NFC标签,然后显示URL(+一些额外数据(

但我希望系统运行在IFTTT上触发网络挂钩的URL(然后在Spotify上触发播放列表…(

到目前为止我所做的:

我使用setup.py安装了nfcpy,并对这些命令进行了一些实验。但是当我运行命令时

python3 tagtool.py --device tty:S0:pn532 -d nfc.ndef.UriRecord -l

它首先返回这个

[main] enable debug output for 'nfc.ndef.UriRecord'
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **

然后,当我用阅读器扫描我的一个NFC标签时——它在URI记录中有一个URL——我得到了这个消息。

Type2Tag 'NXP NTAG213' ID=04EA530A3E4D80
NDEF Capabilities:
readable  = yes
writeable = yes
capacity  = 137 byte
message   = 67 byte
NDEF Message:
record 1
type = 'urn:nfc:wkt:U'
name = ''
data = b'x04maker.ifttt.com/trigger/Playlist_022/with/key/bVTin_XXEEEDDDDEEEEEE'
[main] *** RESTART ***
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **

正如你所看到的,URL就在数据下面(+b\x04,但没有https:\,但我想这很容易更改(。所以基本上我只需要触发它。

我在某个地方读到我可以使用curlify,所以我使用了命令"pip3 install curlify",并对tagtool.py.进行了一些更改

最初的tagtool.py(我认为这是我尝试做的事情中最重要的部分(看起来像这个

if tag.ndef:
print("NDEF Capabilities:")
print("  readable  = %s" % ("no", "yes")[tag.ndef.is_readable])
print("  writeable = %s" % ("no", "yes")[tag.ndef.is_writeable])
print("  capacity  = %d byte" % tag.ndef.capacity)
print("  message   = %d byte" % tag.ndef.length)
if tag.ndef.length > 0:
print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print("record", i + 1)
print("  type =", repr(record.type))
print("  name =", repr(record.name))
print("  data =", repr(record.data))

在新的tagtool2.py中,我将其添加到文档的开头

import curlify
import requests

然后我添加了这行


response = requests.get("https://repr(record.data)")
print(curlify.to_curl(response.request))

也就是说它看起来像这样。这可能在几个方面是错误的:


if tag.ndef:
print("NDEF Capabilities:")
print("  readable  = %s" % ("no", "yes")[tag.ndef.is_readable])
print("  writeable = %s" % ("no", "yes")[tag.ndef.is_writeable])
print("  capacity  = %d byte" % tag.ndef.capacity)
print("  message   = %d byte" % tag.ndef.length)
if tag.ndef.length > 0:
print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print("record", i + 1)
print("  type =", repr(record.type))
print("  name =", repr(record.name))
print("  data =", repr(record.data))
response = requests.get("https://repr(record.data)")
print(curlify.to_curl(response.request))

因为当我试图用NFC标签触发URL时,我会收到这样的消息:

Type2Tag 'NXP NTAG213' ID=04EA530A3E4D80
NDEF Message:
record 1
type = 'urn:nfc:wkt:U'
name = ''
data = b'x04maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE'
[urllib3.connectionpool] Starting new HTTPS connection (1): repr(record.data):443
[nfc.clf] HTTPSConnectionPool(host='repr(record.data)', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0xb579a650>: Failed to establish a new connection: [Errno -2] Name or service not known'))

有人能告诉我我做错了什么吗?如果卷发是正确的方式?

您做错的是存储在NDEF消息中的数据是编码的,您不能使用原始数据打开连接,您必须首先使用正确的类型对其进行解码。(因为编码值中有一个十六进制数(

它也被编码在utf-8中,因此Python将其视为bytes,而不是string类型的对象。

因此,该类型表示它是URI记录类型,因为您使用了"nfc.ndef.UriRecord"(不知道为什么将其称为urn(

因此,十六进制数x04表示https://

不幸的是,我认为没有人为NFC Uri规范专用编码器编写过解码器方法。以下是NDEF URI记录类型的完整链接规范

一旦你用正确的解码值替换了数据中的十六进制字符,你就会得到URLhttps://maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE

一个简单的例子(其中a存储值而不是record.data(

import re
a = b'x04maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE'
a_text = a.decode('utf-8')
x = re.sub('x04', 'https://', a_text)
print(x)
requests.get(x)

然后您可以在解码值上使用requests.get()

这是一个简单但很好的解决方案,可以满足我的需求。

if tag.ndef:
if tag.ndef.length > 0:
#print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print(record.uri)                                       
response = requests.get(record.uri)
print(curlify.to_curl(response.request))

我从一个更复杂的解决方案开始。如果有人遇到类似的问题,我会把它留在这里。

自从第一次拍摄以来,我也清理了一些print((行,我知道我可以再清理一些行,但我会把它们放在这里,这样更容易看到发生了什么。

特别值得注意的是y变量。我留下了一个几乎完美的URL,但由于URL末尾多了一个",我不断出错。

if tag.ndef:
if tag.ndef.length > 0:
for i, record in enumerate(tag.ndef.records):
print(repr(record.data))
print(str(record.data))
org_string = str(record.data)
mod_string = org_string[6:]
y = mod_string.rstrip(mod_string[-1])                    
w = "https://"
print(mod_string)
print(y)
print(w)
response = requests.get(w + y)
print(curlify.to_curl(response.request))

代码可以改进,但它有效,它给了我这个消息,更重要的是,它触发了NFC标签上的URL(我已经扰乱了IFTTT网络挂钩(。

Type2Tag 'NXP NTAG215' ID=04722801E14103
b'x04maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao'
b'x04maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Aoo'
maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao'
maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao
https://
[urllib3.connectionpool] Starting new HTTPS connection (1): maker.ifttt.com:443
[urllib3.connectionpool] https://maker.ifttt.com:443 "GET maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao HTTP/1.1" 200 69
curl -X GET -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Connection: keep-alive' -H 'User-Agent: python-requests/2.21.0' https://maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao
[main] *** RESTART ***
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **

最新更新