本文主要是学习如何采集非结构化的数据,图片。
说明:代码仅供学习,并非其他用途。
这样我们看到想要的图片,就能拿下,看到想要的美女图片,直接拿下好吧!
废话不多说,直接上代码。
第一步:确定图片的网址
这里我选择的是
然后点击选择自己喜欢的类别(人物图片)【狗头保命】,把把网址拿下。
https://sc.chinaz.com/tupian/renwutupian.html
第二步:获取每张图片的地址
这个网址下面解析的内容是解析不到图片的数据的,只能解析到图片所在的地址。
通过requests.get请求方法获得这个网址的HTML,然后通过开发者选项查看网页每张图片的元素div标签位置。
找到所有图片所在的HTML标签位置,然后再解析每张图片所在标签位置的href属性获取图片的地址
这里有个坑,就是获取的href属性值并不是图片实际的地址,只是图片详情页面所在的网址,所以,这里我就直接去img标签下的data-original属性,src属性也是可以的,这样就获得了一张图片的url地址了,其他图片的地址用相同的方法获取url。
代码:
response = requests.get("https://sc.chinaz.com/tupian/jianzhutupian.html", headers="请求头,就是user-agent")
response.encoding = "utf-8"
html = response.content
tree = etree.HTML(html)
divs = tree.xpath('/html/body/div[3]/div[2]/div')
url_list = []
for div in divs:
href = 'https:' + div.xpath('./img/@data-original')[0]
title = div.xpath('./img/@alt')[0]
url_list.append({"href": href, "title": title})
print(url_list)
代码的请求头就用你自己的电脑的吧,这里就没写了【狗头】地址用地点保存到列表里面了。
第三步:获取图片并保存
同样使用requests.get()方法获取图片地址的二进制数据,然后保存到自己的图片目录下
for item in url_list:
url = item['url']
title = item['title']
response = requests.get(url, headers=self.headers)
response.encoding = "utf-8"
with open("./picture/{}.jpg".format(title), "wb") as f:
f.write(response.content)
print(f"{url}下载完成")
这里图片量比较大的时候,解析时间较长,所以我就使用了线程获取图片并保存图片,并对上面的代码进行了封装,这里的请求头,我使用了fake_useragent第三方库生成的请求头,命令行需要执行pip install fake_useragent 一下就可以了。
线程知识,我使用了threading,大家也可以pip install threading一下就可以了,threading下的Thread方法,这个方法传入的参数是执行的函数名target,和函数需要传入的参数args(按顺序写),然后遍历线程,进行回收线程。
# 多线程爬取图片
for picture_url in self.picture_urls:
task = threading.Thread(target=self.get_picture, args=(picture_url['href'], picture_url['title']))
task.start()
# 等待线程完成
for t in threading.enumerate():
task.join()
图片数据采集如上,一起进步,一起学习鸭!有什么错误或疑问,望评论区交流或私聊我呀。
详细的如下
完整代码:
import threading
import requests
from lxml import etree
from fake_useragent import UserAgent
class PictureCrawler():
def __init__(self, url):
self.url = url
self.ua = UserAgent()
self.headers = {
"User-Agent": self.ua.random
}
self.picture_urls = []
# 获取图片的url
def get_picture_url(self):
response = requests.get(self.url, headers=self.headers)
response.encoding = "utf-8"
html = response.content
tree = etree.HTML(html)
divs = tree.xpath('/html/body/div[3]/div[2]/div')
for div in divs:
href = 'https:' + div.xpath('./img/@data-original')[0]
title = div.xpath('./img/@alt')[0]
self.picture_urls.append({"href": href, "title": title})
# print(href, title)
# 获取图片并保存
def get_picture(self, url, title):
response = requests.get(url, headers=self.headers)
response.encoding = "utf-8"
with open("./picture/{}.jpg".format(title), "wb") as f:
f.write(response.content)
print(f"{url}下载完成")
# 运行方法
def run(self):
self.get_picture_url()
# 多线程爬取图片
for picture_url in self.picture_urls:
task = threading.Thread(target=self.get_picture, args=(picture_url['href'], picture_url['title']))
task.start()
# 等待线程完成
for t in threading.enumerate():
task.join()
if __name__ == '__main__':
url = 'https://sc.chinaz.com/tupian/jianzhutupian.html'
task = PictureCrawler(url)
task.run()