Веб-скребкування з Python [закрито]


183

Я хотів би щодня захопити час сходу / заходу сонця з веб-сайту. Чи можна скребки веб-вмісту за допомогою Python? для чого використовуються модулі? Чи є підручник?


3
У Python є кілька варіантів веб-вискоблювання. Я перерахував деякі з варіантів тут у відповідь на подібне питання.
Філіппо

Чому б просто не використовувати вбудований HTML-аналізатор у стандартній бібліотеці Python? Звичайно, для завдання, такого простого і нечастого (лише раз на день), я не бачу причин шукати будь-які інші інструменти. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare

Сподіваюся, цей пост може бути корисним комусь із цього приводу. Хороший підручник для початківця. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Він використовує прекрасну бібліотеку пітонних пітонів для веб-вискоблювання з python.
Саміта Чатуранга

Відповіді:


187

Використовуйте urllib2 у поєднанні з блискучою бібліотекою BeautifulSoup :

import urllib2
from BeautifulSoup import BeautifulSoup
# or if you're using BeautifulSoup4:
# from bs4 import BeautifulSoup

soup = BeautifulSoup(urllib2.urlopen('http://example.com').read())

for row in soup('table', {'class': 'spad'})[0].tbody('tr'):
    tds = row('td')
    print tds[0].string, tds[1].string
    # will print date and sunrise

7
Невеликий коментар: це можна трохи спростити, використовуючи пакет запитів, замінивши рядок 6 на: суп = BeautifulSoup (applications.get (' example.com'). Текст )
D Coetzee,

4
дякую за пораду. пакет запитів ще не існував, коли я написав фрагмент вище ;-)

1
@DerrickCoetzee - ваше спрощення викликає помилку MissingSchema (принаймні в моїй установці). Це працює:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote

@kmote: це те, що я набрав, але я забув backticksкод навколо, і він перетворив його на посилання. Дякую!
D Coetzee

Як ви впевнені, що вміст буде в td і tr. Це може бути в ul і li також правильно?
Шашанк Хегде

62

Я б дуже рекомендував Scrap.

Цитата зі видаленої відповіді:

  • Скрап-сканування швидше, ніж механізувати, оскільки використовує асинхронні операції (зверху закрученими).
  • Scrap має кращу та швидку підтримку для розбору (x) html-файлу поверх libxml2.
  • Скрапія - це зріла рамка з повним унікодом, обробляє перенаправлення, gzipped відповіді, непарні кодування, інтегрований http кеш тощо.
  • Після того, як ви перебуваєте в Scrap, ви зможете написати павука менше ніж за 5 хвилин, який завантажує зображення, створює мініатюри та експортує витягнуті дані безпосередньо в CSV або json.

13
Я не помічав, що це питання було вже 2 роки, я все ще вважаю, що Скрапію слід назвати тут, якщо у когось іншого є таке питання.
Sjaak Trekhaak

4
Скрапія є основою, а тому жахлива і вважає, що це важливіше, ніж ваш проект. Це рамка через жахливі (непотрібні) обмеження Twisted.
користувач1244215

4
@ user1244215: Це фреймворк, тому що кадри хороші. Якщо ви не хочете використовувати його як рамку, ніщо не заважає вам заклинити весь код в одному файлі.
Блендер

1
Але він не підтримує Python 3.x.

17

Я зібрав разом сценарії з моєї роботи зі скребки в цю бібліотеку .

Приклад сценарію для вашого випадку:

from webscraping import download, xpath
D = download.Download()

html = D.get('http://example.com')
for row in xpath.search(html, '//table[@class="spad"]/tbody/tr'):
    cols = xpath.search(row, '/td')
    print 'Sunrise: %s, Sunset: %s' % (cols[1], cols[2])

Вихід:

Sunrise: 08:39, Sunset: 16:08
Sunrise: 08:39, Sunset: 16:09
Sunrise: 08:39, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:11
Sunrise: 08:40, Sunset: 16:12
Sunrise: 08:40, Sunset: 16:13

10

Я настійно пропоную перевірити pyquery . Він використовує синтаксис, схожий на jquery (aka css-like), що робить речі дуже легкими для тих, хто йде з цього фону.

Для вашого випадку це було б щось на зразок:

from pyquery import *

html = PyQuery(url='http://www.example.com/')
trs = html('table.spad tbody tr')

for tr in trs:
  tds = tr.getchildren()
  print tds[1].text, tds[2].text

Вихід:

5:16 AM 9:28 PM
5:15 AM 9:30 PM
5:13 AM 9:31 PM
5:12 AM 9:33 PM
5:11 AM 9:34 PM
5:10 AM 9:35 PM
5:09 AM 9:37 PM

7

Ви можете використовувати urllib2 для створення HTTP-запитів, і тоді ви матимете веб-вміст.

Ви можете отримати це так:

import urllib2
response = urllib2.urlopen('http://example.com')
html = response.read()

Beautiful Soup - це синтаксичний аналізатор пітона, який повинен бути хорошим для вискоблювання екрана.

Зокрема, ось їхній підручник з розбору HTML-документа.

Удачі!


Можливо, ідея встановити максимум на прочитаному байті. response.read (100000000) або щось подібне, щоб ці URL-адреси для ISO не заповнювали оперативну пам'ять. Щасливий видобуток.
andrew pate

4

Я використовую комбінацію Scrapemark (пошук URL - py2) та httlib2 (завантаження зображень - py2 + 3). Scrapemark.py має 500 рядків коду, але використовує регулярні вирази, тому він може бути не таким швидким, не тестував.

Приклад скребкування вашого веб-сайту:

import sys
from pprint import pprint
from scrapemark import scrape

pprint(scrape("""
    <table class="spad">
        <tbody>
            {*
                <tr>
                    <td>{{[].day}}</td>
                    <td>{{[].sunrise}}</td>
                    <td>{{[].sunset}}</td>
                    {# ... #}
                </tr>
            *}
        </tbody>
    </table>
""", url=sys.argv[1] ))

Використання:

python2 sunscraper.py http://www.example.com/

Результат:

[{'day': u'1. Dez 2012', 'sunrise': u'08:18', 'sunset': u'16:10'},
 {'day': u'2. Dez 2012', 'sunrise': u'08:19', 'sunset': u'16:10'},
 {'day': u'3. Dez 2012', 'sunrise': u'08:21', 'sunset': u'16:09'},
 {'day': u'4. Dez 2012', 'sunrise': u'08:22', 'sunset': u'16:09'},
 {'day': u'5. Dez 2012', 'sunrise': u'08:23', 'sunset': u'16:08'},
 {'day': u'6. Dez 2012', 'sunrise': u'08:25', 'sunset': u'16:08'},
 {'day': u'7. Dez 2012', 'sunrise': u'08:26', 'sunset': u'16:07'}]

1

Зробіть життя простішим за допомогою CSS Selectors

Я знаю, що я пізно прийшов на вечірку, але в мене є приємна пропозиція для вас.

Використання BeautifulSoupвже було запропоновано, я вважаю за краще скористатися CSS Selectorsдля скребки даних всередині HTML

import urllib2
from bs4 import BeautifulSoup

main_url = "http://www.example.com"

main_page_html  = tryAgain(main_url)
main_page_soup = BeautifulSoup(main_page_html)

# Scrape all TDs from TRs inside Table
for tr in main_page_soup.select("table.class_of_table"):
   for td in tr.select("td#id"):
       print(td.text)
       # For acnhors inside TD
       print(td.select("a")[0].text)
       # Value of Href attribute
       print(td.select("a")[0]["href"])

# This is method that scrape URL and if it doesnt get scraped, waits for 20 seconds and then tries again. (I use it because my internet connection sometimes get disconnects)
def tryAgain(passed_url):
    try:
        page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
        return page
    except Exception:
        while 1:
            print("Trying again the URL:")
            print(passed_url)
            try:
                page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
                print("-------------------------------------")
                print("---- URL was successfully scraped ---")
                print("-------------------------------------")
                return page
            except Exception:
                time.sleep(20)
                continue 

1

Якщо ми думаємо отримати назву елементів з будь-якої конкретної категорії, то ми можемо це зробити, вказавши назву класу цієї категорії за допомогою селектора css:

import requests ; from bs4 import BeautifulSoup

soup = BeautifulSoup(requests.get('https://www.flipkart.com/').text, "lxml")
for link in soup.select('div._2kSfQ4'):
    print(link.text)

Це часткові результати пошуку:

Puma, USPA, Adidas & moreUp to 70% OffMen's Shoes
Shirts, T-Shirts...Under ₹599For Men
Nike, UCB, Adidas & moreUnder ₹999Men's Sandals, Slippers
Philips & moreStarting 99LED Bulbs & Emergency Lights

0

Ось простий веб-сканер, я використовував BeautifulSoup, і ми шукатимемо всі посилання (якорі), ім'я якого класу - _3NFO0d. Я використовував Flipkar.com, це інтернет-магазин роздрібної торгівлі.

import requests
from bs4 import BeautifulSoup
def crawl_flipkart():
    url = 'https://www.flipkart.com/'
    source_code = requests.get(url)
    plain_text = source_code.text
    soup = BeautifulSoup(plain_text, "lxml")
    for link in soup.findAll('a', {'class': '_3NFO0d'}):
        href = link.get('href')
        print(href)

crawl_flipkart()

0

У Python є хороші варіанти скребти Інтернет. Найкращий з рамок - це скрапія . Це може бути трохи хитро для початківців, тому ось невелика допомога.
1. Встановіть python вище 3,5 (нижчі до 2,7 будуть працювати).
2. Створіть середовище в конді (я це зробив).
3. Встановіть скрап у місці та запустіть звідти.
4. Scrapy shellдасть вам інтерактивний інтерфейс для перевірки коду.
5. Scrapy startproject projectnameстворить рамку.
6. Scrapy genspider spidernameстворить павука. Ви можете створити стільки павуків, скільки захочете. Виконуючи це, переконайтеся, що ви знаходитесь у каталозі проекту.


Найпростіше - використовувати прохання і красивий суп . Перш ніж почати приділяти годину часу, щоб пройти документацію, це вирішить більшість ваших сумнівів. BS4 пропонують широкий спектр парсерів, які ви можете вибрати. Використовуйте user-agentта sleepдля полегшення вискоблювання. BS4 повертає bs.tag, так що використовуйте variable[0]. Якщо js працює, ви не зможете скребти за допомогою запитів і bs4 безпосередньо. Ви можете отримати посилання api, а потім проаналізувати JSON, щоб отримати потрібну інформацію або спробувати selenium.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.