Невозможно правильно напечатать имена в другой функции - PullRequest
0 голосов
/ 23 мая 2018

Я написал скрипт на python, чтобы очистить все names и links, связанные с ним, с целевой страницы веб-сайта с помощью функции .get_links().Затем я создал другую функцию .get_info(), чтобы перейти на другую страницу (используя ссылки, полученные из первой функции), чтобы оттуда отсканировать телефонные номера.

Мне не нужно было создавать вторую функцию вall Если моя цель состояла в том, чтобы разобрать два элемента с этой веб-страницы, поскольку они уже доступны на целевой странице.

Однако, я бы хотел, чтобы мой анализатор вел себя так: распечатать 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)

Вывод, который я получаю:

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

Мой ожидаемый результат:

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

Ответы [ 4 ]

0 голосов
/ 29 мая 2018

У вас уже есть достаточно хороших ответов, но вы можете попробовать это также:

def get_info(session,title,url):
    r = session.get(url)
    soup = BeautifulSoup(r.text,"lxml")
    for items in soup.select("ul.list-unstyled"):
        if len(items.select("a[href^='tel:']")):
            phone = items.select("a[href^='tel:']")[0].text
            break
        else:
            phone = "N/A"
    print(title, phone)

или с какой-то одной строчкой:)

def get_info(session,title,url):
    r = session.get(url)
    soup = BeautifulSoup(r.text,"lxml")
    phone = ([items.select("a[href^='tel:']")[0].text for items in soup.select("ul.list-unstyled") 
              if len(items.select("a[href^='tel:']"))] + ["N/A"])[0]
    print(title, phone) 

Обратите внимание, что "N/A"назначается, если номер телефона не найден (например, Northern Lights Indoor Gardens N/A)

0 голосов
/ 27 мая 2018

Я думаю, что выбор ul.list-unstyled на подстранице слишком широк, их слишком много с контентом, который вам на самом деле не нужен.

Если вы действительно хотите только телефонные номера, выможет непосредственно искать теги a, где href начинается с "tel:".Проблема по-прежнему заключается в том, что эти сайты перечисляют несколько номеров таким образом, обычно 2, где один из них не виден.Тот, который виден, кажется, всегда находится под 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)

и получил следующий результат:

AK Frost (907) 563-9333
AK Fuzzy Budz (907) 644-2838
AK Joint (907) 522-5222
AK Slow Burn (907) 868-1450
Alaska Fireweed (907) 258-9333
Alaskabuds (907) 334-6420
Alaskan Leaf (907) 770-0262
Alaska's Green Light District (907) 644-2839
AM Delight (907) 229-1730
Arctic Herbery (907) 222-1466
Cannabaska (907) 375-9333
Catalyst Cannabis Company (907) 344-0668
Dankorage (907) 279-3265
Enlighten Alaska (907) 290-8559
Great Northern Cannabis (907) 929-9333
Hillside Natural Wellness (907) 868-8639
Hollyweed 907 (907) 929-3331
Raspberry Roots (907) 522-2450
Satori (907) 222-5420
The House of Green (907) 929-3105
Uncle Herb's (907) 561-4372
The Green Spot (907) 354-7044
Denali's Cannabis Cache (907) 683-2633
GOOD (907) 452-5463
Goodsinse (907) 347-7689
Grass Station 49 (907) 374-4420
Green Life Supply (907) 374-4769
One Hit Wonder (844) 420-1448
Pakalolo Supply Company (907) 479-9000
Rebel Roots (907) 455-4055
True Dank (907) 451-4516
The Herbal Cache (907) 783-0420
Denali 420 Recreationals (907) 892-9333
Glacier Valley Shoppe (907) 419-7943
Green Elephant (907) 290-8400
Rainforest Farms (907) 209-2670
The Fireweed Factory (907) 957-2670
Red Run Cannabis Company (907) 283-0800
Cannabis Corner (907) 225-4420
Rainforest Cannabis (907) 247-9333
The Stoney Moose (907) 617-8973
Chena Cannabis (907) 488-0489
The 420 (907) 772-3673
Green Leaf (907) 623-0332
Weed Dudes (907) 623-0605
Remedy Shoppe (907) 983-3345
Fat Tops (907) 953-2470
High Bush Buds (907) 953-9393
Pine Street Cannabis Company (907) 260-3330
Permafrost Distributors (907) 260-7584
Hilltop Premium Green (907) 745-4425
The High Expedition Company (907) 733-0911
Herbal Outfitters (907) 835-4201
Bad Gramm3r (907) 357-0420
Green Degree (907) 376-3155
Green Jar (907) 631-3800
Rosebuds Shatter House (907) 376-9334
Happy Cannabis (907) 305-0292
0 голосов
/ 27 мая 2018

По моему мнению, вам следует использовать базовый словарь JavaScript, который уже содержит ваши данные (и многое другое) в структурированном формате.

Вы можете использовать yaml для преобразования словаря JavaScript в Python dict объект.Вы можете легко получить доступ из полей словаря, таких как id, name, city, address, city, state и т. Д.

Вот рабочий пример:

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)

Результат:

AK Frost (907) 563-9333
AK Fuzzy Budz (907) 644-2838
AK Joint (907) 522-5222
AK Slow Burn (907) 868-1450
Alaska Fireweed (907) 258-9333
...
Bad Gramm3r (907) 357-0420
Green Degree (907) 376-3155
Green Jar (907) 631-3800
Rosebuds Shatter House (907) 376-9334
Happy Cannabis (907) 305-0292
0 голосов
/ 25 мая 2018

Если целью является только получение ожидаемого результата, это должно работать:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...