网页抓取Innerhtml

Web Scraping Innerhtml

我正在尝试使用位于 https://etherscan.io/ 的 BeautifulSoup Python3 库对 open-source 项目进行 WebScrape。具体来说,我想获取一行的 txn 地址,该地址的 "To" 列为 "Contract Creation"(即内部 html)。

this link 处的行为例,使用 firefox 的检查元素功能:

<a href="/address/0x65a0cdb8e79ae3e0c54436362206fd0769335234" title="0x65a0cdb8e79ae3e0c54436362206fd0769335234">Contract Creation</a>

这是一些代码:

    url = https://etherscan.io/txs?block=8086187
    response = requests.get(url, timeout=5)
    content = BeautifulSoup(response.content, "html.parser")
    page = content.findAll('td', attrs={"span": ""})
    page = ''.join(str(page))
    if(page.find("Contract Creation") != -1):
    ## find tx that matches with contract
    for i in range(len(page)):
            if i+1 != len(page):
            if({LINE AT CURRENT PAGE == "Contract Creation"})
                tx.append(TXN address); break;

对于此页面,预期输出应为:

0x48a97150373ca517723db6c39eebcda34719e73a9adb975d5912f21c5a9b4971

我无法提取具体信息。截至目前,我只是确保该页面有合同创建,然后尝试找到它。我可以对其进行硬编码并检查显示

的行
if(page[i[ == "c" and page[i+1] == "o" and page[i+2] == "n"...)
  txn.append(page(i-someNumber:page[i-anotherNumber])

但这效率不高。

更好的是,只获取位于标题中的合同地址。如果我可以抓取特定的 <a href> 行,那么我就可以抓取合约地址:0x65A0cDb8e79Ae3e0c54436362206fd0769335234

您可以尝试使用此代码打印 add

import requests
from bs4 import BeautifulSoup

url = 'https://etherscan.io/txs?block=8086187'

soup = BeautifulSoup(requests.get(url).text, 'lxml')

data = []
for tr in soup.select('#ContentPlaceHolder1_mainrow tr'):
    if tr.select('td'):
        data.append([td for td in tr.select('td')])

for row in data:
    if row[5].text.strip() == 'Contract Creation':
        address = row[5].select_one('a[title]')['title']
        print('txt address={}'.format(address))

这会打印:

txt address=0x65a0cdb8e79ae3e0c54436362206fd0769335234

编辑:您可以 select 包含带有字符串 Contract Creation 的 TD 的整行与此 CSS select 或:

print(soup.select('tr:has(td:contains("Contract Creation"))'))

这会打印:

[<tr><td><span class="hash-tag text-truncate"><a href="/tx/0x48a97150373ca517723db6c39eebcda34719e73a9adb975d5912f21c5a9b4971">0x48a97150373ca517723db6c39eebcda34719e73a9adb975d5912f21c5a9b4971</a></span></td><td class="d-none d-sm-table-cell"><a href="/block/8086187">8086187</a></td><td><span title="Jul-04-2019 05:28:46 PM">1 hr 19 mins ago</span></td><td><span class="hash-tag text-truncate"><a href="/address/0x0031e147a79c45f24319dc02ca860cb6142fcba1">0x0031e147a79c45f24319dc02ca860cb6142fcba1</a></span></td><td class="text-center"><span class="btn btn-xs btn-icon btn-soft-success rounded-circle"><i class="fas fa-long-arrow-alt-right btn-icon__inner"></i></span></td><td><i class="far fa-newspaper text-secondary"></i> <a href="/address/0x65a0cdb8e79ae3e0c54436362206fd0769335234" title="0x65a0cdb8e79ae3e0c54436362206fd0769335234">Contract Creation</a></td><td>0 Ether</td><td><span class="small text-secondary">0<b>.</b>00104386</span></td></tr>]

使用 bs4 4.7.1。您可以使用 nth-of-type:contains 在第 6 列中搜索该字符串。然后使用 :has 获取父行并再次使用 nth-of-type 获取与行关联的第一列值,即 txn。 url 具有查询字符串参数,因此您可以一次提取更多结果。您可以使用 Session 来提高 re-using 连接的效率。

想法是展示组件和匹配和提取的框架。例如,您可以循环 url 的列表。


CSS 选择器:

解释选择器组合的图表:

点击放大


Python3:

from bs4 import BeautifulSoup as bs
import requests

results = [] 

with requests.Session() as s:
    for page in range(1,10):
        r = s.get('https://etherscan.io/txs?ps=51&p={}'.format(page))
        soup = bs(r.content, 'lxml')
        txns_current = [item.text for item in soup.select('tr:has(td:nth-of-type(6):contains("Contract Creation")) td:nth-of-type(1)')]
        if txns_current:
            results.append(txns_current)

final = [item for i in results for item in i]

补充阅读:

Css 选择器在此处广泛介绍:

注意:bs4 4.7.1 支持 :contains:hasnth-of-type 得到广泛支持。

你可以在这里练习选择器: