使用解析器选择器从动态网络 table 抓取数据
Scrape data from a dynamic web table using parsel selector
我正在尝试获取 'From' 列中任何令牌的首次交易地址。由于经常有新交易,因此使 table 动态化,我希望能够使用解析器选择器随时获取此信息。这是我尝试过的方法:
第一步:获取总页数
第二步:将该数字插入 URL 以获得最早的页码。
第三步:遍历'From'列,提取第一个地址。
它returns 一个空列表。我无法弄清楚问题的根源。任何建议将不胜感激。
from parsel import Selector
contract_address = "0x431e17fb6c8231340ce4c91d623e5f6d38282936"
pg_num_url = f"https://bscscan.com/token/generic-tokentxns2?contractAddress={contract_address}&mode=&sid=066c697ef6a537ed95ccec0084a464ec&m=normal&p=1"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
response = requests.get(pg_num_url, headers=headers)
sel = Selector(response.text)
pg_num = sel.xpath('//nav/ul/li[3]/span/strong[2]').get() # Attempting to extract page number
url = f"https://bscscan.com/token/generic-tokentxns2?contractAddress={contract_address}&mode=&sid=066c697ef6a537ed95ccec0084a464ec&m=normal&p={pg_num}" # page number inserted
response = requests.get(url, headers=headers)
sel = Selector(response.text)
addresses = []
for row in sel.css('tr'):
addr = row.xpath('td[5]//a/@href').re('/token/([^#?]+)')[0][45:]
addresses.append(addr)
print(addresses[-1]) # Desired address
似乎该网站正在使用服务器端会话跟踪和安全令牌来增加抓取难度。
我们可以通过复制他们的行为来解决这个问题!
如果您查看 Web Inspector,您会发现在我们第一次连接到该网站时,一些 cookie 会发送给我们:
此外,当我们在其中一个 table 上单击下一页时,我们会看到这些 cookie 被发送回服务器:
最后,table 页面的 url 包含一个叫做 sid
的东西,它通常代表类似 security id
的东西,可以在第一页正文中找到。如果您检查页面源代码,您会发现它隐藏在 javascript:
中
现在我们需要将所有这些放在一起:
- 启动一个请求
Session
,它将跟踪 cookie
- 转到令牌主页并接收 cookie
- 在代币主页找到
sid
- 使用 cookie 和
sid
令牌抓取 table 页面
我已经修改了你的代码,它最终看起来像这样:
import re
import requests
from parsel import Selector
contract_address = "0x431e17fb6c8231340ce4c91d623e5f6d38282936"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
}
# we need to start a session to keep track of cookies
session = requests.session()
# first we make a request to homepage to pickup server-side session cookies
resp_homepage = session.get(
f"https://bscscan.com/token/{contract_address}", headers=headers
)
# in the homepage we also need to find security token that is hidden in html body
# we can do this with simple regex pattern:
security_id = re.findall("sid = '(.+?)'", resp_homepage.text)[0]
# once we have cookies and security token we can build the pagination url
pg_num_url = (
f"https://bscscan.com/token/generic-tokentxns2?"
f"contractAddress={contract_address}&mode=&sid={security_id}&m=normal&p=2"
)
# finally get the page response and scrape the data:
resp_pagination = session.get(pg_num_url, headers=headers)
addresses = []
for row in Selector(resp_pagination.text).css("tr"):
addr = row.xpath("td[5]//a/@href").get()
if addr:
addresses.append(addr)
print(addresses) # Desired address
我正在尝试获取 'From' 列中任何令牌的首次交易地址。由于经常有新交易,因此使 table 动态化,我希望能够使用解析器选择器随时获取此信息。这是我尝试过的方法:
第一步:获取总页数
第二步:将该数字插入 URL 以获得最早的页码。
第三步:遍历'From'列,提取第一个地址。
它returns 一个空列表。我无法弄清楚问题的根源。任何建议将不胜感激。
from parsel import Selector
contract_address = "0x431e17fb6c8231340ce4c91d623e5f6d38282936"
pg_num_url = f"https://bscscan.com/token/generic-tokentxns2?contractAddress={contract_address}&mode=&sid=066c697ef6a537ed95ccec0084a464ec&m=normal&p=1"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
response = requests.get(pg_num_url, headers=headers)
sel = Selector(response.text)
pg_num = sel.xpath('//nav/ul/li[3]/span/strong[2]').get() # Attempting to extract page number
url = f"https://bscscan.com/token/generic-tokentxns2?contractAddress={contract_address}&mode=&sid=066c697ef6a537ed95ccec0084a464ec&m=normal&p={pg_num}" # page number inserted
response = requests.get(url, headers=headers)
sel = Selector(response.text)
addresses = []
for row in sel.css('tr'):
addr = row.xpath('td[5]//a/@href').re('/token/([^#?]+)')[0][45:]
addresses.append(addr)
print(addresses[-1]) # Desired address
似乎该网站正在使用服务器端会话跟踪和安全令牌来增加抓取难度。
我们可以通过复制他们的行为来解决这个问题!
如果您查看 Web Inspector,您会发现在我们第一次连接到该网站时,一些 cookie 会发送给我们:
此外,当我们在其中一个 table 上单击下一页时,我们会看到这些 cookie 被发送回服务器:
最后,table 页面的 url 包含一个叫做 sid
的东西,它通常代表类似 security id
的东西,可以在第一页正文中找到。如果您检查页面源代码,您会发现它隐藏在 javascript:
现在我们需要将所有这些放在一起:
- 启动一个请求
Session
,它将跟踪 cookie - 转到令牌主页并接收 cookie
- 在代币主页找到
sid
- 使用 cookie 和
sid
令牌抓取 table 页面
我已经修改了你的代码,它最终看起来像这样:
import re
import requests
from parsel import Selector
contract_address = "0x431e17fb6c8231340ce4c91d623e5f6d38282936"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
}
# we need to start a session to keep track of cookies
session = requests.session()
# first we make a request to homepage to pickup server-side session cookies
resp_homepage = session.get(
f"https://bscscan.com/token/{contract_address}", headers=headers
)
# in the homepage we also need to find security token that is hidden in html body
# we can do this with simple regex pattern:
security_id = re.findall("sid = '(.+?)'", resp_homepage.text)[0]
# once we have cookies and security token we can build the pagination url
pg_num_url = (
f"https://bscscan.com/token/generic-tokentxns2?"
f"contractAddress={contract_address}&mode=&sid={security_id}&m=normal&p=2"
)
# finally get the page response and scrape the data:
resp_pagination = session.get(pg_num_url, headers=headers)
addresses = []
for row in Selector(resp_pagination.text).css("tr"):
addr = row.xpath("td[5]//a/@href").get()
if addr:
addresses.append(addr)
print(addresses) # Desired address