标签:
有一个很简单的现实情况:我在百度贴吧发了一篇帖子,长达10页,我想写一个爬虫从第一页爬取到第10页,然而条件是我只知道第一页的URL,而且每一页都有下一页的URL,所有的URL都没有规律可循。曾经写爬虫获取URL都是靠规律,靠发现规律,不可否认很多网站当前页的URL和下一页的URL只是阿拉伯数字上的略微区别,经过稍加分析就可以知道全网的URL,这种方法很简单,但是不可靠,如果日后想要爬去的网站URL没有规律可循,岂不是要干瞪眼了。一般网页都有下一页的链接,然后下一页有下一页的链接,像这种通过当前页获取下一页,再从下一页获取下下页,需要用到递归的方法,这里要用到yield关键字和回调函数。
关于yield和回调函数怎么用的,在网上有很多的博客写得非常详细,我只想在这里写一下我编写爬虫的思路,我先写一个很简单的爬虫来理一下yield和回调函数是怎么运作的,这段代码解释了递归方法。
from Queue import Queue
queue = Queue()
class Yie():
def next():
a = 1
for i in range(5):
b = a + 1
yield b
a = b
queue.put(b)
def callback(next):
for i in next():
print i
callback(next)
p = Yie()
下面是爬虫部分
#coding=utf-8
from bs4 import BeautifulSoup
import urllib2
from Queue import Queue
import urllib
url_list = []
queue = Queue()
req_header = {‘User-Agent‘:‘Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6‘}
req_timeout = 20
def next_page():
base_url = ‘http://jandan.net/ooxx/page-1000#comments‘
for i in range(2):
req = urllib2.Request(base_url,None,req_header)
html = urllib2.urlopen(req,None,req_timeout)
#html = urllib2.urlopen(base_url).read()
soup = BeautifulSoup(html)
next_url = soup.find(‘a‘,{‘class‘:‘next-comment-page‘,‘title‘:‘Newer Comments‘}).get(‘href‘)
yield base_url
base_url = next_url
def callback(next_page):
for page in next_page():
queue.put(page)
print ‘There are %d pages‘%queue.qsize()
def get_url_list():
while not queue.empty():
page_url = queue.get()
req = urllib2.Request(page_url,None,req_header)
html = urllib2.urlopen(req,None,req_timeout)
#html = urllib2.urlopen(page_url).read()
soup = BeautifulSoup(html)
img_urls = soup.find_all([‘img‘])
for myimg in img_urls:
Jpgurl = myimg.get(‘src‘)
url_list.append(Jpgurl)
print ‘There are %d pictures‘%len(url_list)
def down():
for down_url in url_list:
urllib.urlretrieve(down_url,‘D:/Python/picture‘+‘/‘+down_url[-11:])
print ‘Now is loading the %dst picture‘%url_list.index(down_url)
def main():
callback(next_page)
get_url_list()
down()
if __name__ == ‘__main__‘:
main()
标签:
原文地址:http://www.cnblogs.com/pylab/p/4621637.html