python 单/多 线程爬虫示例

一、准备

两个比较重要的库:

pip install bs4
#注意是requests,而不是request!
pip install requests

二、示例

#coding=utf-8
#用来解析html文档,然后过滤我们需要的数据
#import bs4
from bs4 import BeautifulSoup
#用来请求网络数据
import requests
import urllib
import os

BASE_PAGE_URL= 'http://www.xxxx.com/photo/list/?page='

# 下载图片的函数
def download_image(url):
    # 文件名:
    split_list = url.split('/')
    filename = split_list.pop()
    # 文件夹:
    path = 'D:\\python_example\\image\\' + filename
    urllib.urlretrieve(url, filename=path)


#这里取1~49页的内容
for x in range(1,50):
    #注意x必须要转化成字符,才能‘+’
    url = BASE_PAGE_URL + str(x)

    #在一个页面中拿到图片的URL
    #而requests.get()就想当于取整个网页,而content是取其中的源代码(整个html的源代码)
    response = requests.get(url)
    content = response.content

    #过滤返回的数据,img-src,就用BS4,参数一是过滤的内容,参数二是过滤引擎
    soup = BeautifulSoup(content,'lxml')

    #寻找并保存符合条件的img标签:class=...
    img_list = soup.find_all('img',attrs={'class':'img-responsive lazy image_dta'})

    #遍历每个img
    for img in img_list:
        src = img['data-original']
        #然后就是下载src,这里要用到urllib
        download_image(src)

三、相关说明

1、因为class是python的保留关键字,若要匹配标签内class的属性,需要特殊的方法,有以下两种:

①在attrs属性用字典的方式进行参数传递 如: attrs={‘class’:‘item-1’}
②BeautifulSoup自带的特别关键字class_ 如: class_ = ‘item-1’

2、有关错误Non-ASCII character '\xe7
在前面加上

>     #coding=utf-8

3、文件夹
注意斜杠是\还是/(因为系统不同斜杠不同),这里用os库就好了,用来架路径,用join来拼接路径
如:

path = os.path.join(‘image’, filename)

4、src与data-ariginal

  • 从img中把其中的src取出来,但是由于如果页面没有加载出来,那么src中的连接就会指向别处,而不是真正的url(如loading.gif)
  • 这里可以查找一下一个属性:data-ariginal,这里面是保存了原来的data url的,不论有没有加载出来,它的值都不变
  • 注意,在data-original中获取的是没有http:的,如果只取它是获取不了图片的,所以要手动加 'http:' +

5、有关get与POST请求:post主要是发送数据到服务器,而从服务器中取数据只需要用get就足够了

6、参考代码
Python单线程爬虫实例(源代码)

四、多线程爬虫

在理解前面的爬虫内容后,这里的多线程爬虫就显得容易了。
1、生产者与消费者

  • 这里我简单说一下:例如超市里面,有商品,自然有工人进行生产,有消费者进行消费,这里涉及了几种情况:

1:商品没有了,卖光了,所以消费者无法再买商品,但是,工人能够继续生产
2:商品仍然有,所以消费者可以买商品,工人也能够继续生产。但是,总不能在售货员补货(当时商店关门)的时候进去吧,所以补货的时候消费者也不能购买(这就涉及‘锁’的概念)
3:在补货之后,货物架无法再放入新的商品,所以工人不工作,而消费者可以购买

2、锁

  • 上面的例子中,锁就是商店的门,关门了,就把共享资源(货物架)锁上了,以阻止一些人们不能获得资源(商品),不然有可能发生死锁

3、python中有关多线程的模块与几个函数

  • threading模块:
  1. Thread()函数:常用的参数有:
    target = functhion name
    args = [function parameter]
    例如有函数get_page(start,pagenum),则用Thread()调用:

    th = threading.Thread(target = get_page, args=[1, 25])

  2. start()函数:(创建线程函数)
    例子如:

    th.start()

  3. Lock()函数:(设置锁)
    用于锁上共享资源:
    例子(伪代码):

    #共享资源
    MONEY = 100
    gLock=threading.Lock()


    gLock.acquire()#加锁
    MONEY - = 1
    gLock.release()#释放锁

3、示例(伪代码)

def get_page(start,pagenum):
   for x in range(start, start + pagenum):
       # 注意x必须要转化成字符,才能‘+’
        url = BASE_PAGE_URL + str(x)
        gPLock.acquire()
       #加入 PAGE_URL_LIST
       ...
        gPLock.release()
        

def get_img():
...
    while True:
        gPLock.acquire()
        if(共享资源数==0):
            gPLock.release()
            break
        else:
        	#获得一个页面地址page_url 
            page_url 
            gPLock.release()
           ...
            # 加锁:添加图片的URL到列表中
            for img in img_list:
               ...
                gILock.acquire()
               #加入IMAGE_URL_LIST
               ...
                gILock.release()

def download_img():
...
    while True:
        gILock.acquire()
        if (共享资源数 == 0):
            gILock.release()
            break
        else:
            #取出图片地址
            ...
            gILock.release()
           #下载IMAGE_URL_LIST中的东西
def main():
#创建线程
...

if  __name__=="__main__":
    main()

4、源代码:
多线程爬虫(源代码)

五、反爬虫机制

传送:Python爬虫之怼破反爬虫机制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值