Python 用pycurl获得许多页面?
我想从一个网站上获得很多页面,比如Python 用pycurl获得许多页面?,python,curl,urllib2,pycurl,Python,Curl,Urllib2,Pycurl,我想从一个网站上获得很多页面,比如 curl "http://farmsubsidy.org/DE/browse?page=[0000-3603]" -o "de.#1" 但是用python获取页面数据,而不是磁盘文件。 有人可以发布pycurlcode来做这件事吗, 或者快速urllib2(不是一次一个),如果可能的话, 或者说“算了吧,卷曲更快更结实”?谢谢您可以将其放入for循环中的bash脚本中 但是,在使用python解析每个页面时,您可能会获得更好的成功。 您将能够获取准确的数据,
curl "http://farmsubsidy.org/DE/browse?page=[0000-3603]" -o "de.#1"
但是用python获取页面数据,而不是磁盘文件。
有人可以发布pycurl
code来做这件事吗,或者快速
urllib2
(不是一次一个),如果可能的话,或者说“算了吧,卷曲更快更结实”?谢谢您可以将其放入for循环中的bash脚本中 但是,在使用python解析每个页面时,您可能会获得更好的成功。 您将能够获取准确的数据,同时将其保存到数据库中。
这里是一个基于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()
所以你有两个问题,让我用一个例子来说明。请注意,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 site=上的一个示例=
也许你真的应该读博士。ppl在这方面花费了大量时间。如果你想用python抓取一个网站,你应该看看scrapy使用和- 抓取首页:
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来完成此任务。我可以推荐您使用的异步模块 例如:
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)
用法非常简单。然后页面成功加载失败的异步_客户端调用回调。您还可以指定并联连接的数量。谢谢Corey;我(线程新手)如何等待它们全部完成?Denis,您可以在main()中的每个线程上调用join()。这将一直阻止,直到线程完成。curl在整个传输过程中保持一个持久连接,为3600 TCP新鲜连接执行shell循环将慢得多…它仍将串行运行。请参阅我的答案,了解可以并行下载多个流的版本。是的,很可能在多个线程中使用pycurl会更快!;-)如果有人试图在python级别使用多线程方法,那么由于PythonGil的问题,它实际上并不像您想象的那样并行获取页面。感谢C编写的curl库,curl库的multi_perfrom真正是多线程的。这是我能想到的最快的方法。下面是一个很好的CurlMulti示例: