Python ile web kazıma [kapalı]


183

Bir web sitesinden günlük gün doğumu / gün batımı zamanlarını almak istiyorum. Python ile web içeriğini kazımak mümkün müdür? kullanılan modüller nelerdir? Herhangi bir öğretici var mı?


3
Python'un web kazıma için çeşitli seçenekleri vardır. Benzer bir soruya yanıt olarak buradaki bazı seçenekleri sıraladım .
filippo

Neden sadece Python Standart Kitaplığı'ndaki yerleşik HTML Ayrıştırıcısını kullanmıyorsunuz? Kesinlikle çok basit ve seyrek bir görev için (günde sadece bir kez), diğer araçları aramak için çok az neden görüyorum. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare

Umarım bu gönderi bu konuda birileri için yararlı olabilir. Yeni başlayanlar için iyi bir öğretici. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Python ile web kazıma için güzel çorba python kütüphanesi kullanır.
Samitha Chathuranga

Yanıtlar:


187

Urllib2'yi muhteşem BeautifulSoup kütüphanesi ile birlikte kullanın :

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
Küçük yorum: bu, satır 6 ile değiştirilerek istek paketi kullanılarak biraz basitleştirilebilir: soup = BeautifulSoup (requests.get (' example.com'). Metin )
D Coetzee

4
Bahşiş için teşekkürler. Yukarıdaki pasajı yazdığımda istek paketi henüz mevcut değildi ;-)

1
@DerrickCoetzee - basitleştirmeniz bir MissingSchema hatası veriyor (en azından kurulumumda). Bu çalışıyor:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote

@kmote: Ben yazdım ama backtickskod etrafında unuttum ve bir bağlantıya dönüştürdü. Teşekkürler!
D Coetzee

İçeriğin td ve tr cinsinden olacağından nasıl emin olabilirsiniz? Ayrıca ul ve li olabilir de değil mi?
Shashank Hegde

62

Gerçekten Scrapy'yi tavsiye ederim.

Silinen bir yanıttan alıntı:

  • Scrap tarama, mekanize etmekten daha hızlıdır çünkü asenkron işlemler kullanır (Twisted'ın üstünde).
  • Scrapy, libxml2'nin üstünde (x) html'yi ayrıştırma için daha iyi ve en hızlı desteğe sahiptir.
  • Scrapy, tam unicode içeren olgun bir çerçevedir, yönlendirmeleri, gzip edilmiş yanıtları, tek kodlamaları, entegre http önbelleğini vb.
  • Scrapy'ye girdikten sonra, görüntüleri indiren, küçük resimler oluşturan ve çıkarılan verileri doğrudan csv veya json'a aktaran 5 dakikadan daha kısa bir sürede bir örümcek yazabilirsiniz.

13
Bu sorunun zaten 2 yaşında olduğunu fark etmedim, yine de başka birinin aynı soruyu sorması durumunda Scrapy'nin burada adlandırılması gerektiğini hissediyorum.
Sjaak Trekhaak

4
Terapi bir çerçevedir ve bu nedenle korkunçtur ve projenizden daha önemli olduğunu düşünmektedir. Twisted'ın korkunç (gereksiz) sınırlamaları nedeniyle bir çerçeve.
user1244215

4
@ user1244215: Bu bir çerçeve çünkü çerçeveler güzel. Bir çerçeve olarak kullanmak istemiyorsanız, tüm kodlarınızı tek bir dosyaya sıkıştıracak hiçbir şey yoktur.
Blender

1
Ancak Python 3.x'i desteklemez.

17

Web kazıma işimdeki komut dosyalarını bu bit kova kitaplığına topladım .

Vakanız için örnek komut dosyası:

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

Çıktı:

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 kontrol şiddetle tavsiye ediyorum . Bu arka plandan gelenler için işleri gerçekten kolaylaştıran jquery benzeri (aka css benzeri) sözdizimi kullanır.

Sizin durumunuz için şöyle bir şey olurdu:

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

Çıktı:

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

HTTP isteklerini yapmak için urllib2'yi kullanabilirsiniz ve ardından web içeriğiniz olacaktır.

Bu şekilde alabilirsiniz:

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

Güzel Çorba , ekran kazıma için iyi olması gereken bir python HTML ayrıştırıcısıdır.

Özellikle, burada bir HTML belgesi ayrıştırma üzerindeki öğretici olduğunu.

İyi şanslar!


Okunan baytlarda bir maksimum belirlemek bir fikir olabilir. response.read (100000000) veya benzeri bir şeyle ISO'ların URL'leri RAM'inizi doldurmaz. Mutlu madencilik.
andrew pate

4

Scrapemark (urls - py2 bulma) ve httlib2 (resim indirme - py2 + 3) kombinasyonunu kullanıyorum . Scrapemark.py 500 kod satırına sahiptir, ancak düzenli ifadeler kullanır, bu yüzden çok hızlı olmayabilir, test etmedi.

Web sitenizi kazıma örneği:

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

Kullanımı:

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

Sonuç:

[{'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

Kullanarak hayatınızı kolaylaştırın CSS Selectors

Partiye geç geldiğimi biliyorum ama sana güzel bir önerim var.

Kullanımı BeautifulSoupzaten önerildi CSS SelectorsHTML içinde veri kazımayı tercih ederim

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

Belirli bir kategoriden öğelerin adını almayı düşünürsek, css selector kullanarak o kategorinin sınıf adını belirterek bunu yapabiliriz:

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)

Bu kısmi arama sonuçlarıdır:

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

İşte basit bir web tarayıcı, BeautifulSoup kullandım ve sınıf adı _3NFO0d olan tüm bağlantıları (çapa) arayacağız. Flipkar.com'u kullandım, çevrimiçi bir perakende mağazası.

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, web'i kazımak için iyi seçeneklere sahiptir. Çerçeveli en iyisi skrapidir . Yeni başlayanlar için biraz zor olabilir, bu yüzden burada biraz yardım.
1. 3.5'in üzerine bir python kurun (2.7 olana kadar daha düşük olanlar)
2. Conda'da bir ortam oluşturun (bunu yaptım).
3. Terapiyi bir yere kurun ve oradan çalıştırın.
4. Scrapy shellsize kodu test etmek için interaktif bir arayüz verecektir.
5. Scrapy startproject projectnamebir çerçeve oluşturacaktır.
6. Scrapy genspider spidernamebir örümcek yaratacaktır. İstediğiniz kadar örümcek oluşturabilirsiniz. Bunu yaparken proje dizininde olduğunuzdan emin olun.


Daha kolay olanı istekleri ve güzel çorbayı kullanmaktır . Başlamadan önce, belgelere bakmak için bir saat zaman verin, şüphelerinizin çoğunu çözecektir. BS4, tercih edebileceğiniz çok çeşitli ayrıştırıcılar sunar. Kazıma işlemini kolaylaştırmak için user-agentve tuşlarını kullanın sleep. BS4 bir bs.tag döndürür, bu yüzden kullanın variable[0]. Js çalışıyorsa, doğrudan istekleri ve bs4 kullanarak kazıyamayacaksınız. Api bağlantısını alabilir ve ihtiyacınız olan bilgileri almak veya denemek için JSON'u ayrıştırabilirsiniz selenium.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.