Используйте красивый суп в очистке нескольких веб-сайтов - PullRequest
2 голосов
/ 16 марта 2020

Я хочу знать, почему списки all_links и all_titles не хотят получать какие-либо записи из списков titles и links. Я попробовал также .extend() метод, и он не помог.

import requests
from bs4 import BeautifulSoup
all_links = []
all_titles = []

def title_link(page_num):
    page = requests.get(
    'https://www.gumtree.pl/s-mieszkania-i-domy-sprzedam-i-kupie/warszawa/page-%d/v%dc9073l3200008p%d'
    % (page_num, page_num, page_num))
    soup = BeautifulSoup(page.content, 'html.parser')
    links = ['https://www.gumtree.pl' + link.get('href')
                for link in soup.find_all('a', class_ ="href-link tile-title-text")]
    titles = [flat.next_element for flat in soup.find_all('a', class_ = "href-link tile-title-text")] 
    print(titles)

for i in range(1,5+1):
    title_link(i)
    all_links = all_links + links
    all_titles = all_titles + titles
    i+=1
    print(all_links)

import pandas as pd
df = pd.DataFrame(data = {'title': all_titles ,'link': all_links})
df.head(100)
#df.to_csv("./gumtree_page_1.csv", sep=';',index=False, encoding = 'utf-8')
#df.to_excel('./gumtree_page_1.xlsx')

Ответы [ 3 ]

1 голос
/ 16 марта 2020

Попробуйте это:

import requests
from bs4 import BeautifulSoup
all_links = []
all_titles = []

def title_link(page_num):
    page = requests.get(
    'https://www.gumtree.pl/s-mieszkania-i-domy-sprzedam-i-kupie/warszawa/page-%d/v%dc9073l3200008p%d'
    % (page_num, page_num, page_num))
    page.encoding = 'utf-8'
    soup = BeautifulSoup(page.content, 'html.parser', from_encoding='utf-8')
    links = ['https://www.gumtree.pl' + link.get('href')
                for link in soup.find_all('a', class_ ="href-link tile-title-text")]
    titles = [flat.next_element for flat in soup.find_all('a', class_ = "href-link tile-title-text")]
    print(titles)
    return links, titles

for i in range(1,5+1):
    links, titles = title_link(i)
    all_links.extend(links)
    all_titles.extend(titles)
    # i+=1 not needed in python
    print(all_links)

import pandas as pd
df = pd.DataFrame(data = {'title': all_titles ,'link': all_links})
df.head(100)

Я думаю, вам просто нужно получить links и titles из title_link(page_num).

Редактировать: убрано ручное увеличение для комментариев

Редактировать: изменилось all_links = all_links + links на all_links.extend(links)

Редактировать: веб-сайт имеет кодировку utf-8, добавлено page.encoding = 'utf-8' и в качестве дополнительной (вероятно, ненужной) меры from_encoding='utf-8' к BeautifulSoup

0 голосов
/ 16 марта 2020

Этот код демонстрирует путаницу в области видимости. titles и links внутри title_link являются локальными для этой функции. Когда функция заканчивается, данные исчезают, и к ним нельзя получить доступ из другой области, такой как main. Используйте ключевое слово return для возврата значений из функций. В этом случае вам нужно будет вернуть пару кортежей titles и links, например return titles, links.

Поскольку функции должны выполнять только одну задачу, необходимость возврата пары показывает, что это возможно. изъян. Такая функция, как title_link, перегружена и, вероятно, должна представлять собой две отдельные функции: одну для получения заголовков и одну для получения ссылок.

Сказав это, функции здесь кажутся преждевременными абстракциями, поскольку операции могут выполняться непосредственно .

Предлагаемое переписывание:

import pandas as pd
import requests
from bs4 import BeautifulSoup

url = "https://www.gumtree.pl/s-mieszkania-i-domy-sprzedam-i-kupie/warszawa/page-%d/v%dc9073l3200008p%d"
data = {"title": [], "link": []}

for i in range(1, 6):
    page = requests.get(url % (i, i, i))
    soup = BeautifulSoup(page.content, "html.parser")
    titles = soup.find_all("a", class_="href-link tile-title-text")
    data["title"].extend([x.next_element for x in titles])
    data["link"].extend("https://www.gumtree.pl" + x.get("href") for x in titles)

df = pd.DataFrame(data)
print(df.head(100))

Другие замечания:

  • i+=1 не требуется; Петли for автоматически перемещаются вперед в Python.
  • (1,5+1) более понятен как (1, 6).
  • Значения списков велики, но если они содержат несколько строк, рассмотрите возможность их записи в виде обычных циклов или создания промежуточной переменной или двух.
  • Импорт должен быть только в верхней части файла. См. PEP-8 .
  • list.extend(other_list) предпочтительнее, чем list = list + other_list, который является медленным и занимает много памяти, создавая полную копию списка.
0 голосов
/ 16 марта 2020

Когда я запустил ваш код, я получил

NameError                                 Traceback (most recent call last)
<ipython-input-3-6fff0b33d73b> in <module>
     16 for i in range(1,5+1):
     17     title_link(i)
---> 18     all_links = all_links + links
     19     all_titles = all_titles + titles
     20     i+=1

NameError: name 'links' is not defined

Это указывает на проблему - переменная с именем links не определена в глобальной области (где вы добавляете ее в all_links). Вы можете прочитать о python областях здесь . Вам нужно return ссылки и заголовки от title_link. Нечто похожее на это:

def title_link(page_sum):
    # your code here
    return links, titles


for i in range(1,5+1):
    links, titles = title_link(i)
    all_links = all_links + links
    all_titles = all_titles + titles
    print(all_links)
...