การขูดเว็บด้วย Python [ปิด]


183

ฉันต้องการคว้าเวลาพระอาทิตย์ขึ้น / ตกทุกวันจากเว็บไซต์ จะสามารถขูดเนื้อหาเว็บด้วย Python ได้หรือไม่ โมดูลที่ใช้มีอะไรบ้าง? มีบทช่วยสอนหรือไม่


3
Python มีหลายตัวเลือกสำหรับการขูดเว็บ ฉันระบุตัวเลือกบางส่วนที่นี่เพื่อตอบคำถามที่คล้ายกัน
ฟิลิปโป

ทำไมไม่ใช้ตัวแยกวิเคราะห์ HTML ที่มีอยู่แล้วใน Python Standard Library? แน่นอนว่าสำหรับงานที่เรียบง่ายและไม่บ่อยนัก (เพียงวันละครั้ง) ฉันเห็นเหตุผลเล็กน้อยที่จะค้นหาเครื่องมืออื่น ๆ docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare

หวังว่าโพสต์นี้อาจมีประโยชน์กับใครบางคนเกี่ยวกับเรื่องนี้ บทแนะนำที่ดีสำหรับผู้เริ่มต้น samranga.blogspot.com/2015/08/web-scraping-beginner-python.htmlมันใช้ห้องสมุด python ซุปที่สวยงามสำหรับการขูดเว็บด้วยหลาม
Samitha Chathuranga

คำตอบ:


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 ด้วย: soup = BeautifulSoup (requests.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 ยังใช่ไหม?
Shashank Hegde

62

ฉันอยากแนะนำ Scrapy

อ้างอิงจากคำตอบที่ถูกลบ:

  • การรวบรวมข้อมูลเรื่องที่สนใจนั้นเร็วกว่ากลไกเนื่องจากใช้การดำเนินการแบบอะซิงโครนัส (ด้านบนของ Twisted)
  • Scrapy มีการสนับสนุนที่ดีกว่าและเร็วที่สุดสำหรับการแยกวิเคราะห์ (x) html ที่ด้านบนของ libxml2
  • Scrapy เป็นเฟรมเวิร์คสำหรับผู้ใหญ่ที่มียูนิโค้ดเต็มจัดการการเปลี่ยนเส้นทางตอบ gzipped การเข้ารหัสคี่แคช http แบบบูรณาการ ฯลฯ
  • เมื่อคุณอยู่ใน Scrapy คุณสามารถเขียนแมงมุมในเวลาน้อยกว่า 5 นาทีที่ดาวน์โหลดรูปภาพสร้างภาพขนาดย่อและส่งออกข้อมูลที่แยกแล้วไปยัง csv หรือ json โดยตรง

13
ฉันไม่ได้สังเกตว่าคำถามนี้มีอายุ 2 ปีแล้ว แต่ก็ยังรู้สึกว่าควรจะตั้งชื่อ Scrapy ที่นี่ในกรณีที่คนอื่นมีคำถามเดียวกัน
Sjaak Trekhaak

4
Scrapy เป็นเฟรมเวิร์กดังนั้นจึงน่ากลัวและคิดว่ามันสำคัญกว่าโปรเจ็กต์ของคุณ มันเป็นกรอบเพราะข้อ จำกัด ที่น่ากลัว (ไม่จำเป็น) ของ Twisted
user1244215

4
@ user1244215: มันเป็นเฟรมเวิร์กเพราะเฟรมเวิร์คนั้นดี หากคุณไม่ต้องการใช้เป็นเฟรมเวิร์กไม่มีอะไรที่จะหยุดคุณไม่ให้โค้ดทั้งหมดของคุณติดขัดในไฟล์เดียว
Blender

1
แต่มันไม่รองรับ Python 3.x

17

ฉันรวบรวมสคริปต์จากเว็บของฉันที่ทำงานร่วมกันในไลบรารี bit-bucketนี้

สคริปต์ตัวอย่างสำหรับกรณีของคุณ:

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

ฉันขอแนะนำอย่างยิ่งให้ตรวจสอบการค้นหาโดยละเอียด มันใช้ไวยากรณ์ jquery-like (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เป็น parser HTML ของ python ที่ควรจะดีสำหรับการขูดหน้าจอ

โดยเฉพาะอย่างยิ่งนี่คือบทช่วยสอนเกี่ยวกับการแยกวิเคราะห์เอกสาร HTML

โชคดี!


อาจเป็นความคิดที่จะตั้งค่าสูงสุดในการอ่านไบต์ response.read (100000000) หรือบางอย่างดังนั้น URL เหล่านั้นสำหรับ ISO จะไม่เติม RAM ของคุณ การขุดมีความสุข
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 selector:

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 มีตัวเลือกที่ดีในการขูดเว็บ ที่ดีที่สุดที่มีกรอบเป็นscrapy อาจเป็นเรื่องยุ่งยากเล็กน้อยสำหรับผู้เริ่มต้นดังนั้นนี่คือความช่วยเหลือเล็กน้อย
1. ติดตั้งไพ ธ อนที่สูงกว่า 3.5 (ต่ำกว่าจนถึง 2.7 จะใช้งานได้)
2. สร้างสภาพแวดล้อมใน conda (ฉันทำสิ่งนี้)
3. ติดตั้ง scrapy ที่ตำแหน่งและเรียกใช้จากที่นั่น
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ที่จะได้รับข้อมูลที่คุณต้องการหรือลอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.