一、准备
两个比较重要的库:
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模块:
-
Thread()函数:常用的参数有:
target = functhion name
args = [function parameter]
例如有函数get_page(start,pagenum),则用Thread()调用:th = threading.Thread(target = get_page, args=[1, 25])
-
start()函数:(创建线程函数)
例子如:th.start()
-
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、源代码:
多线程爬虫(源代码)