как сделать гусеничный скребок по сайту с помощью bs4 - PullRequest
0 голосов
/ 01 сентября 2018

Я написал скрипт для очистки цитат для очистки цитат и фамилий авторов. В этом проекте я использую запросы для получения кода страницы и bs4 для анализа HTML. Я использую цикл while для перехода по пагинационной ссылке на следующие страницы, но я хочу, чтобы мой код прекратил работать, когда не осталось страниц. Мой код работает, но он не остановится.

Вот мой код:

from bs4 import BeautifulSoup as bs
import requests

def scrape():
    page = 1
    url = 'http://quotes.toscrape.com'
    r = requests.get(url)
    soup = bs(r.text,'html.parser')
    quotes = soup.find_all('span',attrs={"class":"text"})
    authors = soup.find_all('small',attrs={"class":"author"})
    p_link = soup.find('a',text="Next")

    condition = True
    while condition:
        with open('quotes.txt','a') as f:
            for i in range(len(authors)):
                f.write(quotes[i].text+' '+authors[i].text+'\n')
        if p_link not in soup:
            condition = False
            page += 1
            url = 'http://quotes.toscrape.com/page/{}'.format(page)
            r = requests.get(url)
            soup = bs(r.text,'html.parser')
            quotes = soup.find_all('span',attrs={"class":"text"})
            authors = soup.find_all('small',attrs={"class":"author"})
            condition = True
        else:
            condition = False

    print('done')


scrape()

1 Ответ

0 голосов
/ 01 сентября 2018

Потому что p_link никогда не бывает в супе. Я нахожу две причины для этого.

  1. Вы ищете его, используя текст «Далее». Но похоже, что фактический ссылка «Далее» + пробел + стрелка вправо

  2. Тег содержит атрибут 'href', который указывает на следующую страницу. Для каждой страницы это будет иметь другое значение.

Также нет условия создания разницы как False внутри цикла while для первого блока if. В любом случае вы устанавливаете его обратно в конец блока.

Итак ...

Вместо поиска по следующему, используйте:

soup.find('li',attrs={"class":"next"})

А для условия используйте:

if soup.find('li',attrs={"class":"next"}) is None:
   condition = False

Наконец, если вы хотите написать цитаты из последней страницы, я предлагаю вам поставить часть «запись в файл» в конце. Или избегайте всего этого .. вот так:

from bs4 import BeautifulSoup as bs
import requests

def scrape():
    page = 1
    while True:

        if page == 1:
            url = 'http://quotes.toscrape.com'
        else:
            url = 'http://quotes.toscrape.com/page/{}'.format(page)

        r = requests.get(url)
        soup = bs(r.text,'html.parser')

        quotes = soup.find_all('span',attrs={"class":"text"})
        authors = soup.find_all('small',attrs={"class":"author"})

        with open('quotes.txt','a') as f:
            for i in range(len(authors)):
                f.write(str(quotes[i].encode("utf-8"))+' '+str(authors[i].encode("utf-8"))+'\n')       

        if soup.find('li',attrs={"class":"next"}) is None:
            break

        page+=1

    print('done')


scrape()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...