Пытаясь получить лиды от визг - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь получить информацию от yelp, используя python и Beautifulsoup, но я не могу перехватить поля для имени телефона и адреса wesbite (необязательно). Я получаю следующую ошибку, вот мой код, я пытаюсь найти и найти другое решение, но они не работают для меня.

Вот мой код

from bs4 import BeautifulSoup
import requests
import sys
import csv
import requests, re, json
## Get the min and max page numbers
pagenum=0

maxpage =0
## loop go thourgh the pages
while pagenum <= maxpage:
    newsu =pagenum
    newsu = str(newsu)
    csvname = 'cardealers'+newsu+'.csv';
    csvfile = open(csvname , 'w',encoding="utf-8")
    csv_writer = csv.writer(csvfile)
    csv_writer.writerow(['Business name', 'phone' , 'address'] )

    headers = {'User-Agent':'Mozilla/5.0'}
    r = requests.get('https://www.yelp.com/search?find_desc=Used%20Car%20Dealers&find_loc=New%20York%2C%20NY&ns=1&sortby=review_count&start={}'.format(pagenum), headers = headers)
    p = re.compile(r'PRELOADED_STATE__ = (.*?);')
    data = json.loads(p)
    print(data)
    pagenum =pagenum+1
    for item in data['searchResult']['results']:
        name = item['businessName']
        phone=item['phone']
        address= ([item['address'],item['city'], item['state'], item['postalcode']])
        csv_writer.writerow([name, phone , address ])
        print(name)
    csvfile.close()

вот сообщение об ошибке.

Traceback (последний вызов был последним): файл "\ Python \ Python36 \ scraper \ scrape.py", строка 22, в файле данных = json .loads (p) " \ Python \ Python36 \ lib \ json__init __. Py ", строка 348, в формате загрузки" not {! R} ". (S. class . name )) Ошибка типа: JSON объект должен быть str, байтами или байтовым массивом, а не 'SRE_Pattern'

1 Ответ

2 голосов
/ 07 февраля 2020

вы пытаетесь прочитать в строке, которая не json формат.

По сути, это то, что вы делаете:

data = json.loads('THIS IS JUST A STRING. NOT IN A JSON FORMAT')

, поэтому вы хотите сделать что-то вроде : data = json.loads(p.findall(r.text))

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

Кроме того, вы ничего не просматриваете. Вы начинаете с pagenum = 0, с maxpage page = 0 и запускаете, пока pagenum <= maxpage, что означает, что он будет работать вечно. </p>

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

Кроме того, почему:

newsu =pagenum
newsu = str(newsu)

просто выполните newsu = str(pagenum). Вы действительно хотите отдельный файл для каждой итерации? Я просто положил его в 1 файл:

from bs4 import BeautifulSoup
import requests
import pandas as pd
import json
import math

## Get the min and max page numbers
pagenum=0
results = pd.DataFrame()
with requests.Session() as s:
        headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'}
        url = 'https://www.yelp.com/search?find_desc=Used%20Car%20Dealers&find_loc=New%20York%2C%20NY&ns=1&sortby=review_count&start={}'.format(pagenum)
        r = s.get(url, headers = headers)
        soup = BeautifulSoup(r.text, 'html.parser')

        scripts = soup.find_all('script')
        for script in scripts:
            if '<!--{' in script.text:
                jsonStr = script.text.split('<!--')[-1].split('-->')[0]
                jsonData = json.loads(jsonStr)

        totalPages = jsonData['searchPageProps']['searchResultsProps']['paginationInfo']['totalResults']
        resultsPerPage = jsonData['searchPageProps']['searchResultsProps']['paginationInfo']['resultsPerPage']
        totalPages = math.ceil(totalPages/resultsPerPage)

        ## loop go through the pages
        for pagenum in range(0,totalPages+1):
            url = 'https://www.yelp.com/search?find_desc=Used%20Car%20Dealers&find_loc=New%20York%2C%20NY&ns=1&sortby=review_count&start={}'.format(pagenum)
            r = s.get(url, headers = headers)
            soup = BeautifulSoup(r.text, 'html.parser')

            scripts = soup.find_all('script')
            for script in scripts:
                if '<!--{' in script.text:
                    jsonStr = script.text.split('<!--')[-1].split('-->')[0]
                    jsonData = json.loads(jsonStr)


            for each in jsonData['searchPageProps']['searchResultsProps']['searchResults']:
                if 'searchResultBusiness' in each.keys():
                    busiName = each['searchResultBusiness']['name']
                    phone = each['searchResultBusiness']['phone']
                    address = each['searchResultBusiness']['formattedAddress']

                    temp_df = pd.DataFrame([[busiName, phone, address]], columns=['Business name', 'phone' , 'address'])
                    results = results.append(temp_df, sort=False).reset_index(drop=True)
            print ('Aquired page: %s' %pagenum)



results.to_csv('cardealers.csv', index=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...