Python学习笔记--BeautifulSoup、urllib、threading模块

在开源中国社区中偶然发现了这个:屌丝娱乐(终极版)-->从百度贴吧下载妹子图,于是就按照上面的代码自己改写了一遍。从中主要学习了BeautifulSoup、urllib、threading等三个模块的应用。

1、BeautifulSoup模块(简称BS模块):python的html文档解析器

python2.7中默认没有安装BS模块,在使用该模块之前,先在BeautifulSoup这里下载安装包,我下载的是:beautifulsoup4-4.2.1.tar.g
z,下载完之后解压在一个目录下,然后用bat文件进行安装,bat文件的内容为:

python setup.py install
pause
至此,BS模块的安装完成。类似的PY模块都可以按照上面的方法进行安装。

在用BS对Html文档进行解析之前,我们需要先获得该html文档。如果要解析的文档是一个文件,可以用文件的句柄作为BS初始化的参数;如果解析的文档是一个str,则直接用该str做为BS的参数即可,代码为:

from bs4 import BeautifulSoup
fp = open("index.html" , "r") #打开html文档
soup1 = BeautifulSoup( fp )  
soup2 = BeautifulSoup( "<html>data</html>")
得到BS对象之后,对html文档解析最主要的一个步骤就是查找元素。BS提供了find(args1[,args2,args3...])和find_all(
args1[,args2,args3...])两个方法,find用于查找第一个出现的元素对象,返回元素;find_all用于查找所有满足条件的对象,返回一个包含元素的列表。args是查找的参数,可以是条件表达式,也可以是正则表达式。

得到要查找的元素之后,我们还需要获得元素的属性、name、value等信息,假设当前已经查找到元素x,得到各信息的代码为:

x.attrs['href'] 或者 x['href']  #获得元素x的"href"属性的值。
x.name   #获得元素的名称
x.text   #获得元素的文本


2、urllib模块

在网页处理中,该模块主要有两个比较有用的方法,分别是urlopen和urlretrieve

import urllib
url = "www.google.com"
path = "C:\\test.html"
wp = urllib.urlopen( url )
content = wp.read() 
fp = open( path , "w")
fp.write( content )

其中用到的urlopen()打开一个特定的URL字符串与web连接,并返回了文件类的对象。语法结构如下:

urllib.urlopen(url[, data[, proxies]]) :

urlopen()的对象方法如下:

    *     read() :读取所有内容;
    *     readline():读出一行; 
    *     readlines() :读出所有行并返回一个列表
    *     fileno():返回文件句柄
    *     close():关闭URL的连接
    *     info():返回一个httplib.HTTPMessage 对象,表示远程服务器返回的头信息;
    *     getcode():返回Http状态码。如果是http请求,200表示请求成功完成;404表示网址未找到;
    *     geturl():返回请求的url;

import urllib
def cbk(a, b, c):
    '''回调函数
    @a: 已经下载的数据块
    @b: 数据块的大小
    @c: 远程文件的大小
    '''
    print a , b , c
    per = 100.0 * a * b / c
    if per > 100:
        per = 100
    print '%.2f%%' % per
url = "www.google.com"
path = "C:\\test.html"
urllib.urlretrieve( url , path , cbk )  #下载url的资源并存储在path中,可用于下载图片,文档等


3、threading模块
Thread 是threading模块中最重要的类之一,可以使用它来创建线程。有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法;另一种是创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入。下面分别举例说明。先来看看通过继承threading.Thread类来创建线程的例子:
import threading 
count = 0 
class Counter( threading.Thread ):
    def __init__( self ,lock ,threadName ):
        super( Counter ,self ).__init__( name = threadName ) 
        self.lock = lock 
    def run( self ): 
        global count 
        self.lock.acquire()
        for i in range( 1000 ):
            count += 1 
        self.lock.release()
lock = threading.Lock() 
for i in range(5) :
    Counter( lock , "thread-" + str(i) ).start()
print count 

另外一种创建线程的方法为:

import threading 
count = 0
lock = threading.Lock() 
def doAdd():
    global count , lock 
    lock.acquire() 
    for i in range(1000):
        count += 1 
    lock.release()
for i in range(5):
    threading.Thread( target=doAdd , args=() ,name="thread-"+str(i) ).start()
print count 

综合上面的知识,并结合OSChina上的代码,下面的代码实现从httpurl制定的贴吧中下载所有图片,然后保存在当前目录一个叫"DownloadPictrue"的文件夹下面。具体的代码为:


#-*-coding=gbk-*-
from bs4 import BeautifulSoup 
import urllib
import re
import threading 
import os 

titleUrl = {}
chunkNum = 100 

def find_title( soup ):
    Eab = soup.find_all('a' , target="_blank" , class_="j_th_tit")
    for i ,aa in enumerate(Eab) :
        titleUrl[i] = baseUrl + aa['href']
        #print aa['title'].encode('gbk') , titleUrl[i] 

def get_soup_from_url( url ):
    mid = urllib.urlopen( url )
    ch = mid.read() 
    return BeautifulSoup( ch )

def get_img_url_from_url( url ):
    soup = get_soup_from_url( url ) 
    imgElements = soup.find_all( 'img' , src=re.compile('imgsrc') )
    return imgElements 

def get_last_name_of_url( url ):
    pos = url.rfind('/') ;
    return url[ pos+1 : ]

    
def get_img_from_url( url , path ):
    filename = path + os.sep + get_last_name_of_url( url ) ;
    fw = open( filename , "wb" ) ;
    fc = urllib.urlopen( url ) ;
    while True :
        chunkD = fc.read( chunkNum * 1024 ) 
        if len( chunkD ) == 0 :
            break 
        fw.write( chunkD ) 
    fw.close() 
    fc.close()

def get_tie_ba_img_url_from_url( url ):
    img = {}
    titleHtml = get_soup_from_url( url )
    totlePage = titleHtml.find('span' , class_="red")
    if totlePage.text == "" :
        itotlePage = 1 
    else:
        itotlePage = int( totlePage.text )
    img[0] = get_img_url_from_url( url ) ;
    for i in range(1 , itotlePage ) :
        img[i] = get_img_url_from_url( url + "&pn=" + str(i+1) )
    
    for i in range( itotlePage ) :
        for element in img[i] :
            threading.Thread( target = get_img_from_url , args = ( element['src'] , path ) ).start()
        
        
baseUrl = "http://tieba.baidu.com"
httpurl = "http://tieba.baidu.com/f?kw=%C0%EE%D2%E3"
returnHtml = urllib.urlopen( httpurl ) 
returnHtml = returnHtml.read()
soup = BeautifulSoup( returnHtml )
find_title( soup ) 
path = "DownloadPictrue" 
if( not os.path.exists( path ) ):    os.makedirs( path ) 
for i in titleUrl :
    threading.Thread( target=get_tie_ba_img_url_from_url , args=( titleUrl[i] + "?see_lz=1" , ) ).start()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值