美丽的汤网页刮:我如何刮这个特定的html结构

2024-04-25 01:39:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图在一个具有这种html结构的Webpg上搜寻商店名称及其以下商店地址:

<div class="post_content entry-content" itemprop="articleBody">
<p>...</p>
<p>...</p>
<h2>1. SHOP NAME</h2>
<p>...</p>
<p>...</p>
<p><strong>Address</strong>: Dhoby Ghaut 238889<br />
<strong>Prices: </strong>Starting from SGD3.50 <br />
<strong>Websites</strong>:<a href="https://..." target="_blank" rel="noopener"></a></p>

<h2>2. SHOP NAME</h2>
.
.
<h2>3. SHOP NAME</h2>
.
.
</div>

他们不为每个单独的商店展示使用类。我想把地址弄出来有困难,有人知道怎么做吗?你知道吗

这是我获取店铺名称的代码:

url= requests.get('https://avenueone.sg/recipes-food/bubble-tea-brands-singapore/').text

shop= []
address= []

soup = BeautifulSoup(url,'lxml')

for row in soup.find_all("h2"): 
    shop.append(row.text)
    for line in row.find_all(string='Address'):
        address.append(line.text)
import re
for i in soup.find('div', class_='post_content entry-content'):
    for x in soup.find_all(re.compile("^Address")):
        address.append(line.text)

我可以将商店名称列表检索到数据框中,但不能检索到它们对应的地址。 有人能帮我吗?你知道吗


Tags: textnameindiv名称foraddress地址
3条回答

您可以使用以下css选择器和regex。regex只是用来检查地址是否真的指向一个网站的url,如果是的话,还可以检索这个url。需要bs4 4.7.1+,因为我使用:contains以地址强标记为目标/

from bs4 import BeautifulSoup as bs
import requests, re

r = requests.get('https://avenueone.sg/recipes-food/bubble-tea-brands-singapore/')
soup = bs(r.content, 'lxml')
names = [i.text.replace('\xa0',' ') for i in soup.select('.post_content p + h2')]
addresses = [i.next_sibling.replace('\xa0','').replace(':','').strip() if not re.search(r'See this|See their',i.next_sibling) else i.parent.a['href'] for i in soup.select('strong:contains("Address")') ]
results = dict(zip(names,addresses))
print(results)

结果样本:

enter image description here

因为没有类,所以我不会使用BeautifulSoup并返回正则表达式来查找响应中的地址。如果格式是稳定的,并且如您在问题中所述,我们可以使用以下正则表达式:

import re


address_pattern = "<strong>Address</strong>:(.+?)<br />"
addresses = re.findall(address_pattern, url)

我们仍然需要把地址和店名联系起来,但如何联系起来取决于你没有给出的一些假设。如果每个商店只有一个地址,并且商店存储在变量shops中,那么我们可以zip(shops, addresses)。你知道吗

如果我们必须考虑到某些商店名称下缺少或有多个地址,我们可以将响应拆分为商店条目块,并分别查找每个商店名称下的地址:

addresses = [
    re.findall(address_pattern, chunk) 
    for chunk in url.split("<h2>")[1:]
]

现在我们有一个列表(可能有多个或没有地址),它们位于两个"<h2>"标记之间。现在zip(shops, addresses)将为我们提供一个元组迭代器,其中第一个元素是商店名称,第二个元素是地址列表(可能是空的)。你知道吗

为了得到地址,你可以按照下面给出的逻辑

>>> for row in soup.find_all('div', {'class':'post_content entry-content'}):
    for el in row.find_all('p'):
        if 'Address' in el.get_text():
            print(el.get_text().split('\n')[0])
            break # remove break in your actual code.


Address: Dhoby Ghaut MRT, 60 Orchard Road, #B2-06, Dhoby Ghaut 238889

相关问题 更多 >