получить много страниц с Pycurl? - PullRequest
3 голосов
/ 24 декабря 2009

Я хочу получить много страниц с веб-сайта, например

curl "http://farmsubsidy.org/DE/browse?page=[0000-3603]" -o "de.#1"

но получите данные страниц в python, а не дисковые файлы. Может кто-нибудь, пожалуйста, напишите pycurl код, чтобы сделать это,
или быстро urllib2 (не по одному), если это возможно,
или еще сказать "забудь, скручиваемость быстрее и надежнее"? Спасибо

Ответы [ 6 ]

6 голосов
/ 20 августа 2010

Итак, у вас есть 2 проблемы, и позвольте мне показать вам один пример. Обратите внимание, что pycurl уже выполнил многопоточность / не по одному без вашей тяжелой работы.

#! /usr/bin/env python

import sys, select, time
import pycurl,StringIO

c1 = pycurl.Curl()
c2 = pycurl.Curl()
c3 = pycurl.Curl()
c1.setopt(c1.URL, "http://www.python.org")
c2.setopt(c2.URL, "http://curl.haxx.se")
c3.setopt(c3.URL, "http://slashdot.org")
s1 = StringIO.StringIO()
s2 = StringIO.StringIO()
s3 = StringIO.StringIO()
c1.setopt(c1.WRITEFUNCTION, s1.write)
c2.setopt(c2.WRITEFUNCTION, s2.write)
c3.setopt(c3.WRITEFUNCTION, s3.write)

m = pycurl.CurlMulti()
m.add_handle(c1)
m.add_handle(c2)
m.add_handle(c3)

# Number of seconds to wait for a timeout to happen
SELECT_TIMEOUT = 1.0

# Stir the state machine into action
while 1:
    ret, num_handles = m.perform()
    if ret != pycurl.E_CALL_MULTI_PERFORM:
        break

# Keep going until all the connections have terminated
while num_handles:
    # The select method uses fdset internally to determine which file descriptors
    # to check.
    m.select(SELECT_TIMEOUT)
    while 1:
        ret, num_handles = m.perform()
        if ret != pycurl.E_CALL_MULTI_PERFORM:
            break

# Cleanup
m.remove_handle(c3)
m.remove_handle(c2)
m.remove_handle(c1)
m.close()
c1.close()
c2.close()
c3.close()
print "http://www.python.org is ",s1.getvalue()
print "http://curl.haxx.se is ",s2.getvalue()
print "http://slashdot.org is ",s3.getvalue()

Наконец, этот код в основном основан на примере на сайте pycurl =. =

Может быть, вы действительно должны прочитать документ. на это тратится огромное количество времени.

3 голосов
/ 25 декабря 2009

вот решение, основанное на urllib2 и потоках.

import urllib2
from threading import Thread

BASE_URL = 'http://farmsubsidy.org/DE/browse?page='
NUM_RANGE = range(0000, 3603)
THREADS = 2

def main():
    for nums in split_seq(NUM_RANGE, THREADS):
        t = Spider(BASE_URL, nums)
        t.start()

def split_seq(seq, num_pieces):
    start = 0
    for i in xrange(num_pieces):
        stop = start + len(seq[i::num_pieces])
        yield seq[start:stop]
        start = stop

class Spider(Thread):
    def __init__(self, base_url, nums):
        Thread.__init__(self)
        self.base_url = base_url
        self.nums = nums
    def run(self):
        for num in self.nums:
            url = '%s%s' % (self.base_url, num)
            data = urllib2.urlopen(url).read()
            print data

if __name__ == '__main__':
    main()
1 голос
/ 07 октября 2012

Я могу порекомендовать вам модуль async пользователя human_curl

Смотрите пример:

from urlparse import urljoin 
from datetime import datetime

from human_curl.async import AsyncClient 
from human_curl.utils import stdout_debug

def success_callback(response, **kwargs):
    """This function call when response successed
    """
    print("success callback")
    print(response, response.request)
    print(response.headers)
    print(response.content)
    print(kwargs)

def fail_callback(request, opener, **kwargs):
    """Collect errors
    """
    print("fail callback")
    print(request, opener)
    print(kwargs)

with AsyncClient(success_callback=success_callback,
                 fail_callback=fail_callback) as async_client:
    for x in xrange(10000):
        async_client.get('http://google.com/', params=(("x", str(x)),)
        async_client.get('http://google.com/', params=(("x", str(x)),),
                        success_callback=success_callback, fail_callback=fail_callback)

Использование очень просто. Затем страница успешно загружена из неуспешного async_client обратного вызова. Также вы можете указать номер на параллельных соединениях.

1 голос
/ 05 мая 2012

Использование BeautifulSoup4 и запросов -

Захватить главную страницу:

page = Soup(requests.get(url='http://rootpage.htm').text)

Создать массив запросов:

from requests import async

requests = [async.get(url.get('href')) for url in page('a')]
responses = async.map(requests)

[dosomething(response.text) for response in responses]

Запросы требует Gevent для этого.

1 голос
/ 06 февраля 2011

Если вы хотите сканировать веб-сайт, используя python, вам стоит взглянуть на scrapy http://scrapy.org

1 голос
/ 24 декабря 2009

Вы можете просто поместить это в скрипт bash внутри цикла for.

Однако вы можете добиться большего успеха при разборе каждой страницы с помощью python. http://www.securitytube.net/Crawling-the-Web-for-Fun-and-Profit-video.aspx Вы сможете получить точные данные и одновременно сохранить их в БД. http://www.securitytube.net/Storing-Mined-Data-from-the-Web-for-Fun-and-Profit-video.aspx

...