Quét web bằng Python [đã đóng]


183

Tôi muốn lấy thời gian mặt trời mọc / mặt trời lặn hàng ngày từ một trang web. Có thể cạo nội dung web bằng Python không? các mô-đun được sử dụng là gì? Có hướng dẫn nào không?


3
Python có một số tùy chọn để quét web. Tôi liệt kê một số tùy chọn ở đây để trả lời cho một câu hỏi tương tự.
filippo

Tại sao không sử dụng Trình phân tích cú pháp HTML tích hợp trong Thư viện chuẩn Python? Chắc chắn đối với một nhiệm vụ rất đơn giản và không thường xuyên (chỉ một lần một ngày), tôi thấy ít lý do để tìm kiếm bất kỳ công cụ nào khác. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare

Hy vọng bài viết này có thể hữu ích cho ai đó về điều này. Một hướng dẫn tốt cho người mới bắt đầu. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Nó sử dụng thư viện trăn súp đẹp mắt để quét web với python.
Samitha Chathuranga

Câu trả lời:


187

Sử dụng urllib2 kết hợp với thư viện BeautifulSoup rực rỡ :

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
Nhận xét nhỏ: điều này có thể được đơn giản hóa một chút bằng cách sử dụng gói yêu cầu bằng cách thay thế dòng 6 bằng: soup = BeautifulSoup (request.get (' example.com'). Text )
D Coetzee

4
cảm ơn vì tiền hỗ trợ. gói yêu cầu chưa tồn tại, khi tôi viết đoạn trích ở trên ;-)

1
@DerrickCoetzee - đơn giản hóa của bạn gây ra lỗi MissingSchema (ít nhất là trên cài đặt của tôi). Công việc này:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote

@kmote: đó là những gì tôi đã gõ nhưng tôi quên backticksmã xung quanh và nó đã chuyển đổi nó thành một liên kết. Cảm ơn!
D Coetzee

Làm thế nào bạn chắc chắn rằng nội dung sẽ ở td và tr. Nó có thể ở ul và li cũng phải không?
Shashank Hegde

62

Tôi thực sự muốn giới thiệu Scrapy.

Trích dẫn từ một câu trả lời đã bị xóa:

  • Thu thập dữ liệu phế liệu nhanh nhất so với cơ giới hóa vì sử dụng các hoạt động không đồng bộ (trên đầu Twisted).
  • Scrapy có hỗ trợ tốt hơn và nhanh nhất để phân tích cú pháp (x) html trên đầu trang libxml2.
  • Scrapy là một khung trưởng thành với đầy đủ unicode, xử lý các chuyển hướng, phản hồi được nén, mã hóa lẻ, bộ đệm http tích hợp, v.v.
  • Khi bạn vào Scrapy, bạn có thể viết một con nhện trong vòng chưa đầy 5 phút để tải xuống hình ảnh, tạo hình thu nhỏ và xuất dữ liệu được trích xuất trực tiếp sang csv hoặc json.

13
Tôi không nhận thấy câu hỏi này đã được 2 tuổi, vẫn cảm thấy Scrapy nên được đặt tên ở đây trong trường hợp người khác có cùng câu hỏi.
Sjaak Trekhaak

4
Phế liệu là một khuôn khổ, và do đó thật kinh khủng và nghĩ rằng nó quan trọng hơn dự án của bạn. Đó là một khuôn khổ vì những hạn chế khủng khiếp (không cần thiết) của Twisted.
dùng1244215

4
@ user1244215: Đó là một khung vì các khung là tốt. Nếu bạn không muốn sử dụng nó làm khung, không có gì ngăn bạn kẹt tất cả mã của bạn vào một tệp.
Máy xay sinh tố

1
Nhưng nó không hỗ trợ Python 3.x.

17

Tôi đã thu thập các tập lệnh từ công việc quét web của mình vào thư viện bit-xô này .

Kịch bản ví dụ cho trường hợp của bạn:

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

Đầu ra:

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

Tôi sẽ đề nghị kiểm tra pyquery . Nó sử dụng cú pháp giống như jquery (hay còn gọi là css), điều này làm cho mọi thứ thực sự dễ dàng đối với những người đến từ nền tảng đó.

Đối với trường hợp của bạn, nó sẽ là một cái gì đó như:

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

Đầu ra:

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

Bạn có thể sử dụng urllib2 để thực hiện các yêu cầu HTTP và sau đó bạn sẽ có nội dung web.

Bạn có thể có được nó như thế này:

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

Beautiful Soup là một trình phân tích cú pháp HTML python được cho là tốt cho việc quét màn hình.

Cụ thể, đây là hướng dẫn của họ về phân tích tài liệu HTML.

Chúc may mắn!


Nó có thể là một ý tưởng để thiết lập tối đa trên byte đọc. answer.read (100000000) hoặc một cái gì đó để các URL cho ISO không lấp đầy RAM của bạn. Chúc mừng khai thác.
pate

4

Tôi sử dụng kết hợp Scrapemark (tìm url - py2) và omelib2 (tải hình ảnh - py2 + 3). Trào lưu có 500 dòng mã, nhưng sử dụng các biểu thức thông thường, vì vậy nó có thể không quá nhanh, đã không kiểm tra.

Ví dụ để cạo trang web của bạn:

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

Sử dụng:

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

Kết quả:

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

Làm cho cuộc sống của bạn dễ dàng hơn bằng cách sử dụng CSS Selectors

Tôi biết tôi đã đến muộn để dự tiệc nhưng tôi có một gợi ý hay cho bạn.

Việc sử dụng BeautifulSoupđã được đề xuất Tôi thà sử dụng CSS Selectorsđể cạo dữ liệu trong 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

Nếu chúng tôi nghĩ đến việc lấy tên của các mục từ bất kỳ danh mục cụ thể nào thì chúng tôi có thể làm điều đó bằng cách chỉ định tên lớp của danh mục đó bằng cách sử dụng bộ chọn 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)

Đây là kết quả tìm kiếm một phần:

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

Đây là một trình thu thập dữ liệu web đơn giản, tôi đã sử dụng BeautifulSoup và chúng tôi sẽ tìm kiếm tất cả các liên kết (neo) tên lớp là _3NFO0d. Tôi đã sử dụng Flipkar.com, nó là một cửa hàng bán lẻ trực tuyến.

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 có các tùy chọn tốt để quét web. Một trong những tốt nhất với một khung là phế liệu . Nó có thể là một chút khó khăn cho người mới bắt đầu, vì vậy đây là một chút giúp đỡ.
1. Cài đặt python trên 3.5 (những cái thấp hơn cho đến 2.7 sẽ hoạt động).
2. Tạo một môi trường trong conda (Tôi đã làm điều này).
3. Cài đặt phế liệu tại một địa điểm và chạy vào đó.
4. Scrapy shellsẽ cung cấp cho bạn một giao diện tương tác để kiểm tra mã của bạn.
5. Scrapy startproject projectnamesẽ tạo ra một khung.
6. Scrapy genspider spidernamesẽ tạo ra một con nhện. Bạn có thể tạo nhiều nhện như bạn muốn. Trong khi làm điều này đảm bảo bạn đang ở trong thư mục dự án.


Một cách dễ dàng hơn là sử dụng các yêu cầusúp đẹp . Trước khi bắt đầu cho một giờ thời gian để xem qua tài liệu, nó sẽ giải quyết hầu hết các nghi ngờ của bạn. BS4 cung cấp một loạt các trình phân tích cú pháp mà bạn có thể chọn. Sử dụng user-agentsleepđể làm cho cạo dễ dàng hơn. BS4 trả về một bs.tag vì vậy sử dụng variable[0]. Nếu có js đang chạy, bạn sẽ không thể cạo bằng cách sử dụng các yêu cầu và bs4 trực tiếp. Bạn có thể lấy liên kết api sau đó phân tích JSON để lấy thông tin bạn cần hoặc thử selenium.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.