Каков тип возврата метода find_all в Beautiful Soup? - PullRequest
1 голос
/ 21 февраля 2020
from bs4 import BeautifulSoup, SoupStrainer 
from urllib.request import urlopen
import pandas as pd 
import numpy as np 
import re
import csv
import ssl
import json
from googlesearch import search
from queue import Queue
import re 

links = []
menu = []
filtered_menu = []




def contains(substring, string):
     if substring.lower() in string.lower():
         return True
     else:
         return False




for website in search("mr puffs", tld="com", num=1, stop=1, country="canada", pause=4): 
 links.append(website)


soup = BeautifulSoup(urlopen(links.pop(0)), features="html.parser")
menu = soup.find_all('a', href=True)

for string in menu:
    if contains("contact", string):
      filtered_menu.append(string)


print(filtered_menu)

Привет, я создаю webscarper, который будет извлекать контактную информацию с сайтов. Однако для этого мне нужно перейти на страницу контактов сайта. Используя библиотеку googlesearch, код ищет ключевое слово и помещает все результаты (до определенного предела) в список. Для простоты в этом коде мы просто вставляем первую ссылку. Теперь по этой ссылке я создаю красивый объект супа и извлекаю все остальные ссылки на веб-сайте (поскольку контактная информация обычно отсутствует на главной странице). Я помещаю эти ссылки в список под названием menu.

Теперь я хочу отфильтровать меню только по тем ссылкам, в которых есть "contact". Пример: «www.smallBusiness.com/our-services» будет удалено из нового списка, а «www.smallBusiness.com/contact» или «www.smallBusiness.com/contact-us» останутся в списке.

Я определил метод, который проверяет, находится ли подстрока в строка. Однако я получаю следующее исключение: TypeError: объект 'NoneType' не вызывается. Я попытался использовать regex, выполнив re.search, но он говорит, что ожидаемый тип строки или байтового значения отсутствует в параметрах.

Я думаю, это потому, что возвращаемый тип find_all не является строкой , Это, вероятно, что-то еще, что я не могу найти в документах. Если это так, как я могу преобразовать его в строку.

Как и просили в ответе ниже, вот что дает список меню печати:

Отсюда я просто хочу извлечь выделенные ссылки:

вот изображение

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

BeautifulSoup.find_all() тип bs4.element.ResultSet (который фактически является списком)

Отдельные элементы find_all(), в вашем случае переменная, которую вы называете "string", имеет тип bs4.element.Tag.

Поскольку ваша contains функция ожидает type str, ваша для l oop должна выглядеть примерно так:

for string in menu:
    if contains("contact", str(string)):
      filtered_menu.append(string)
0 голосов
/ 21 февраля 2020

Вот как я это сделал, чтобы найти в Google поисковые термины, введенные пользователем, а затем очистить все URL-адреса от серпов. Программа продолжает посещать каждую из этих ссылок напрямую и очищать текст от них.

Может быть, вы могли бы изменить это для своих целей?

 #First-stage scrape of Google

    headers = {"user-agent": USER_AGENT}
    URL=f"https://google.com/search?q={squery}"
    URL2=f"https://google.com/search?q={squery2}"
    URL3=f"https://google.com/search?q={squery3}"
    URL4=f"https://google.com/search?q={squery4}"
    resp=requests.get(URL, headers=headers)
    resp2=requests.get(URL2, headers=headers)
    resp3=requests.get(URL3, headers=headers)
    resp4=requests.get(URL4, headers=headers)

    results=[]
    s2results=[]
    s3results=[]
    s4results=[]
    def scrapeURL(a,b,c):
        if a.status_code == 200:
            print("Searching Google for information about: ", c)
            soup = BeautifulSoup(a.content, "html.parser")
            for g in soup.find_all('div', class_='r'):
                anchors = g.find_all('a')
                if anchors:
                    link = anchors[0]['href']
                    title = g.find('h3').text
                    item = {
                    link
                    }
                    b.append(item)
                else:
                    print("Couldn't scrape URLS from first phase")
        else: 
            print("Could not perform search. Status code: ",a.status_code)
    #Create list of urls and format to enable second scrape


    scrapeURL(resp,results,query)
    scrapeURL(resp2,s2results,query2)
    scrapeURL(resp3,s3results,query3)
    scrapeURL(resp4,s4results,query4)
    #Create list of urls and format to enable second scrape
    def formaturls(res,resstorage):
        a=0
        listurls=str(res)
        listurls=listurls.replace("[","")
        listurls=listurls.replace("{","")
        listurls=listurls.replace("'}","")
        listurls=listurls.replace("]","")
        listurls=listurls.lower()
        re=listurls.split(",")
        for items in re:
            s=str(re[a])
            resstorage.append(s)
            a=a+1 
    qresults=[]
    q2results=[]
    q3results=[]
    q4results=[]
    formaturls(results,qresults)
    formaturls(s2results,q2results)
    formaturls(s3results,q3results)
    formaturls(s4results,q4results)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...