无法在另一个函数中以正确的方式打印名称

2024-09-15 04:34:39 发布

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

我用python编写了一个脚本,使用.get_links()函数从网站的登录页上抓取所有的names以及与之相关的links。然后我创建了另一个函数.get_info()来访问另一个页面(使用从第一个函数派生的链接),以便从那里获取电话号码。在

我根本不需要创建第二个函数,如果我的目标是解析该网页中的两个项目,因为它们已经在登录页面中可用。在

但是,我希望解析器的行为方式是在第二个函数中打印names(从第一个函数中继承)以及那里的phone numbers。最重要的是,我不想去掉第二个函数中定义的for loop。如果for loop不在第二个函数中,那么问题就不会出现。不使用for loop我已经可以得到所需的输出。在

这是我目前为止的剧本:

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

url = "https://potguide.com/alaska/marijuana-dispensaries/"

def get_links(link):
    session = requests.Session()
    session.headers['User-Agent'] = 'Mozilla/5.0'
    r = session.get(link)
    soup = BeautifulSoup(r.text,"lxml")
    for items in soup.select("#StateStores .basic-listing"):
        name = items.select_one("h4 a").text
        namelink = urljoin(link,items.select_one("h4 a").get("href"))  ##making it a fully qualified url
        get_info(session,name,namelink)          ##passing session in order to reuse it

def get_info(session,title,url):
    r = session.get(url)
    soup = BeautifulSoup(r.text,"lxml")
    for items in soup.select("ul.list-unstyled"):  ##if I did not use for loop I could get the output as desired.
        try:
            phone = items.select_one("a[href^='tel:']").text
        except:
            phone = ""
        print(title,phone)

if __name__ == '__main__':
    get_links(url)

我的输出:

^{pr2}$

我的预期产出:

AK Frost (907) 563-9333
AK Fuzzy Budz (907) 644-2838

Tags: 函数textimportinfoloopurlforget
3条回答

我认为子页面中ul.list-unstyled的选择范围太广了,其中有太多你实际上并不想要的内容。在

如果您真的只需要电话号码,可以直接搜索a标记,其中href以“tel:”开头。问题仍然是这些网站以这种方式列出多个数字,通常是2,其中一个是不可见的。可见的那个似乎总是在Nath下div.col-md-3。我试过了:

def get_info(session,title,url):
    r = session.get(url)
    soup = BeautifulSoup(r.text,"lxml")
    for a_phone in soup.select("div.col-md-3 a[href^='tel:']"):        
        print(title, a_phone.text)

得到如下结果:

^{pr2}$

在我看来,您应该使用底层javascript字典,它已经以结构化格式保存了数据(以及更多)。在

可以使用yaml将javascript字典转换为Pythondict对象。您可以轻松地从字典中访问字段,如idnamecityaddresscitystate

下面是一个有效的例子:

import json, re, requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import yaml

url = "https://potguide.com/alaska/marijuana-dispensaries/"

def get_links(link):
    session = requests.Session()
    session.headers['User-Agent'] = 'Mozilla/5.0'
    r = session.get(link)
    soup = BeautifulSoup(r.text,"lxml")
    for items in soup.select("#StateStores .basic-listing"):
        name = items.select_one("h4 a").text
        namelink = urljoin(link,items.select_one("h4 a").get("href"))
        get_info(session, name, namelink)

def get_info(session, title, url):    
    response = requests.get(url)
    soup = BeautifulSoup(response.content, "lxml")
    script = next((i for i in map(str, soup.find_all("script", type="text/javascript"))
                   if 'mapOptions' in i), None)
    if script:
        js_dict = script.split('__mapOptions = ')[1].split(';\n')[0]
        d = yaml.load(js_dict)
        print(title, d['mapStore']['phone'])

get_links(url)

结果:

^{pr2}$

如果目标仅仅是获得预期的产出,这应该是可行的:

def get_info(session,title,url):
    r = session.get(url)
    soup = BeautifulSoup(r.text,"lxml")
    for items in soup.select("ul.list-unstyled"):
        try:
           phone = items.select_one("a[href^='tel:']").text
        except:
           # skip item and continue
           continue  
        else:
           # exception wasn't rised, you have the phone
           print(title,phone)
           break

相关问题 更多 >