Python3 - веб-чистка zomato - несколько страниц - PullRequest
2 голосов
/ 31 марта 2019

Я не могу сгенерировать вывод для чего-либо, кроме страницы 1 (на одной странице 15 ресторанов, и это все, что я получаю (всего 15 выводов). Похоже, что вывод со страницы 1 заменяется страницей 2 и т. Д. .

Я попытался добавить диапазон страниц в записку, но все равно вернулся только с 15 результатами (удаление только одной страницы).

import requests
import pandas
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

for num in range(1,5):
    url = 'https://www.zomato.com/auckland/restaurants?gold_partner=1&page={}'.format(num)
response = requests.get(url,headers=headers)
content = response.content
soup = BeautifulSoup(content,"html.parser")

top_rest = soup.find_all("div",attrs={"class": "col-s-16 search_results mbot"})
list_tr = top_rest[0].find_all("div",attrs={"class": "js-search-result-li even status 1"})
list_rest =[]

for tr in list_tr:
    dataframe ={}
    dataframe["1.rest_name"] = (tr.find("a",attrs={"class": "result-title hover_feedback zred bold ln24 fontsize0"})).text.replace('\n', ' ')
    dataframe["2.rest_address"] = (tr.find("div",attrs={"class": "col-m-16 search-result-address grey-text nowrap ln22"})).text.replace('\n', ' ')
    list_rest.append(dataframe)
    list_rest

df = pandas.DataFrame(list_rest)
df.to_csv("zomato_res26.csv",index=False)

Я ожидаю получить список из более чем 40 ресторанов с их названиями и местоположением, но на данный момент похоже, что я получаю только 15 ресторанов на страницу, где

Ответы [ 2 ]

2 голосов
/ 31 марта 2019

Измените отступ, переместите создание списка, list_rest, из цикла и добавьте к нему в цикле.Кроме того, измените кодировку для вывода на encoding='utf-8-sig', чтобы правильно обрабатывать присутствующие символы.Вы можете получить количество страниц с помощью int(soup.select_one('.pagination-number b:last-child').text).

Я также добавил requests.Session() для повторного использования соединения.

import requests
import pandas
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

list_rest =[]

with requests.Session() as s:
    for num in range(1,5):
        url = 'https://www.zomato.com/auckland/restaurants?gold_partner=1&page={}'.format(num)
        response = s.get(url,headers=headers)
        content = response.content
        soup = BeautifulSoup(content,"html.parser")

        top_rest = soup.find_all("div",attrs={"class": "col-s-16 search_results mbot"})
        list_tr = top_rest[0].find_all("div",attrs={"class": "js-search-result-li even status 1"})

        for tr in list_tr:
            dataframe ={}
            dataframe["1.rest_name"] = (tr.find("a",attrs={"class": "result-title hover_feedback zred bold ln24 fontsize0"})).text.replace('\n', ' ')
            dataframe["2.rest_address"] = (tr.find("div",attrs={"class": "col-m-16 search-result-address grey-text nowrap ln22"})).text.replace('\n', ' ')
            list_rest.append(dataframe)

df = pandas.DataFrame(list_rest)
df.to_csv(r"zomato_res26.csv", sep=',', encoding='utf-8-sig',index = False )

Если вы хотите зациклить всестраницы и используйте более быстрые селекторы со списком:

import requests
import pandas
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

list_rest =[]

def getInfo(soup):
    names = [item.text.strip() for item in soup.select('.result-title')]
    addresses =  [item.text.strip() for item in soup.select('.search-result-address')]
    row = list(zip(names, addresses))
    return row

with requests.Session() as s:   
        url = 'https://www.zomato.com/auckland/restaurants?gold_partner=1&page={}'
        response = s.get(url.format(1),headers=headers)
        content = response.content
        soup = BeautifulSoup(content,"lxml")
        numPages = int(soup.select_one('.pagination-number b:last-child').text)
        list_rest.append(getInfo(soup))

        if numPages > 1:
            for page in range(2, numPages + 1):
                response = s.get(url.format(page),headers=headers)
                content = response.content
                soup = BeautifulSoup(content,"lxml")
                list_rest.append(getInfo(soup))

final_list = [item for sublist in list_rest for item in sublist]
df = pandas.DataFrame(final_list, columns = ['1.rest_name', '2.rest_address'])
df.to_csv(r"zomato_res26.csv", sep=',', encoding='utf-8-sig',index = False )
1 голос
/ 31 марта 2019

Что делать, если вы не знаете номер последней страницы !!! Следующий скрипт позаботится об этой вещи нумерации страниц. Он проанализирует номер последней страницы и затем создаст цикл для их обхода, чтобы выбрать названия ресторанов и их номера телефонов.

import pandas
import requests
from bs4 import BeautifulSoup

url = "https://www.zomato.com/auckland/restaurants?gold_partner=1&page="

def get_content(session,link):
    session.headers["User-Agent"] = "Mozilla/5.0"
    response = session.get(link)
    soup = BeautifulSoup(response.text,"lxml")
    dataframe = []
    last_page = soup.select_one(".pagination-number b:nth-of-type(2)").text
    for item_url in range(1,int(last_page)+1):
        res = session.get(f"{link}{item_url}")
        sauce = BeautifulSoup(res.text,"lxml")
        for elem in sauce.select(".search-card"):
            d = {}
            d['name'] = elem.select_one("a[data-result-type='ResCard_Name']").get_text(strip=True)
            d['phone'] = elem.select_one("a.res-snippet-ph-info").get("data-phone-no-str")
            dataframe.append(d)

    return dataframe

if __name__ == '__main__':
    with requests.Session() as session:
        item = get_content(session,url)
        df = pandas.DataFrame(item)
        df.to_csv("zomato_res26.csv",index=False)
...