Mengikis web dengan Python [ditutup]

183

Saya ingin mengambil waktu matahari terbit / terbenam setiap hari dari situs web. Apakah mungkin untuk mengikis konten web dengan Python? apa saja modul yang digunakan? Apakah ada tutorial yang tersedia?

eozzy
sumber
3
Python memiliki beberapa opsi untuk pengikisan web. Saya menyebutkan beberapa opsi di sini sebagai jawaban atas pertanyaan serupa.
filippo
Mengapa tidak menggunakan Parser HTML bawaan di Python Standard Library? Tentu saja untuk tugas yang sangat sederhana dan jarang (hanya sekali sehari), saya melihat sedikit alasan untuk mencari alat lain. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare
Semoga postingan ini bermanfaat bagi seseorang mengenai hal ini. Tutorial yang bagus untuk pemula. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Menggunakan pustaka python sup yang indah untuk pengikisan web dengan python.
Samitha Chathuranga

Jawaban:

187

Gunakan urllib2 dalam kombinasi dengan pustaka BeautifulSoup yang brilian :

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
lesmana
sumber
7
Komentar kecil: ini bisa sedikit disederhanakan menggunakan paket permintaan dengan mengganti baris 6 dengan: soup = BeautifulSoup (requests.get (' example.com'). Teks )
D Coetzee
4
terima kasih atas tipnya. paket permintaan belum ada, ketika saya menulis cuplikan di atas ;-)
1
@DerrickCoetzee - penyederhanaan Anda menimbulkan kesalahan MissingSchema (setidaknya pada instalasi saya). Ini berfungsi:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote
@kmote: itu yang saya ketikkan tapi saya lupa backtickskode dan mengubahnya menjadi tautan. Terima kasih!
D Coetzee
Bagaimana Anda yakin bahwa konten akan berada dalam td dan tr. Bisa di ul dan li juga kan?
Shashank Hegde
62

Saya sangat merekomendasikan Scrapy.

Kutipan dari jawaban yang dihapus:

  • Perayapan Scrapy lebih cepat daripada mekanisasi karena menggunakan operasi asinkron (di atas Twisted).
  • Scrapy memiliki dukungan lebih baik dan tercepat untuk parsing (x) html di atas libxml2.
  • Scrapy adalah kerangka kerja matang dengan unicode penuh, menangani pengalihan, respons gzip, penyandian aneh, cache http terintegrasi, dll.
  • Setelah Anda menjadi Scrapy, Anda dapat menulis laba-laba dalam waktu kurang dari 5 menit yang mengunduh gambar, membuat thumbnail dan mengekspor data yang diekstraksi langsung ke csv atau json.
Sjaak Trekhaak
sumber
13
Saya tidak melihat pertanyaan ini sudah berusia 2 tahun, masih merasa bahwa Scrapy harus disebutkan di sini kalau-kalau ada orang lain yang memiliki pertanyaan yang sama.
Sjaak Trekhaak
4
Scrapy adalah kerangka kerja, dan karenanya mengerikan dan menganggapnya lebih penting daripada proyek Anda. Ini kerangka kerja karena keterbatasan Twisted yang mengerikan (tidak perlu).
user1244215
4
@ user1244215: Ini kerangka kerja karena kerangka kerja bagus. Jika Anda tidak ingin menggunakannya sebagai kerangka kerja, tidak ada yang menghentikan Anda dari kemacetan semua kode Anda ke dalam satu file.
Blender
1
Tetapi itu tidak mendukung Python 3.x.
17

Saya mengumpulkan skrip dari pekerjaan pengikisan web saya ke pustaka bit-bucket ini .

Contoh skrip untuk kasus Anda:

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])

Keluaran:

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
hoju
sumber
10

Saya sangat menyarankan memeriksa pyquery . Menggunakan sintaks jquery-like (alias css-like) yang membuat segalanya sangat mudah bagi mereka yang datang dari latar belakang itu.

Untuk kasus Anda, itu akan menjadi seperti:

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

Keluaran:

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
scottmrogowski
sumber
7

Anda dapat menggunakan urllib2 untuk membuat permintaan HTTP, dan kemudian Anda akan memiliki konten web.

Anda bisa mendapatkannya seperti ini:

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

Beautiful Soup adalah parser HTML python yang seharusnya bagus untuk pengikisan layar.

Secara khusus, berikut adalah tutorial mereka tentang penguraian dokumen HTML.

Semoga berhasil!

danben
sumber
Mungkin ide untuk menetapkan maksimum pada byte yang dibaca. response.read (100000000) atau sesuatu sehingga URL untuk ISO tidak mengisi RAM Anda. Selamat menambang.
andrew pate
4

Saya menggunakan kombinasi Scrapemark (menemukan url - py2) dan httlib2 (mengunduh gambar - py2 + 3). The scrapemark.py memiliki 500 baris kode, tetapi menggunakan ekspresi reguler, jadi mungkin tidak begitu cepat, tidak menguji.

Contoh untuk mengikis situs web Anda:

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] ))

Pemakaian:

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

Hasil:

[{'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'}]
Nils Lindemann
sumber
1

Jadikan hidup Anda lebih mudah dengan menggunakan CSS Selectors

Saya tahu saya datang terlambat ke pesta tetapi saya punya saran yang bagus untuk Anda.

Menggunakan BeautifulSoupsudah disarankan saya lebih suka menggunakan CSS Selectorsuntuk mengikis data dalam 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 
Umair
sumber
1

Jika kita berpikir untuk mendapatkan nama item dari kategori tertentu maka kita dapat melakukannya dengan menentukan nama kelas dari kategori tersebut menggunakan pemilih 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)

Ini adalah hasil pencarian parsial:

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
SIM
sumber
0

Berikut ini adalah perayap web sederhana, saya menggunakan BeautifulSoup dan kami akan mencari semua tautan (jangkar) yang namanya kelas _3NFO0d. Saya menggunakan Flipkar.com, ini adalah toko ritel online.

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()
Atul Chavan
sumber
0

Python memiliki opsi bagus untuk mengikis web. Yang terbaik dengan kerangka kerja adalah kasar . Ini bisa sedikit rumit untuk pemula, jadi ini sedikit bantuan.
1. Instal python di atas 3.5 (yang lebih rendah sampai 2,7 akan berfungsi).
2. Buat lingkungan di conda (saya melakukan ini).
3. Instal goresan di lokasi dan jalankan dari sana.
4. Scrapy shellakan memberi Anda antarmuka interaktif untuk menguji kode Anda.
5. Scrapy startproject projectnameakan membuat kerangka kerja.
6. Scrapy genspider spidernameakan membuat laba-laba. Anda dapat membuat laba-laba sebanyak yang Anda inginkan. Saat melakukan ini pastikan Anda berada di dalam direktori proyek.


Yang lebih mudah adalah menggunakan permintaan dan sup yang indah . Sebelum mulai memberi satu jam waktu untuk membaca dokumentasi, itu akan menyelesaikan sebagian besar keraguan Anda. BS4 menawarkan berbagai parser yang dapat Anda pilih. Gunakan user-agentdan sleepuntuk membuat goresan lebih mudah. BS4 mengembalikan bs.tag jadi gunakan variable[0]. Jika ada js yang berjalan, Anda tidak akan dapat mengikis menggunakan permintaan dan bs4 secara langsung. Anda bisa mendapatkan tautan api kemudian mengurai JSON untuk mendapatkan informasi yang Anda butuhkan atau coba selenium.

Chris D'mello
sumber