python爬取下厨房网站首页图片request+bs4_html


注:东西太多,总结的不算太全,系统学习的话,出门右拐B站等你

爬虫:

  • 一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息。

网页爬取

工具

  • ​CURL​​:cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。
  • 基本使用方法:
curl url (获取网站全部信息)
curl -i url(获取该网址的文本信息以及协议头部信息)
curl -x proxy url(使用代理获取网页文本信息)
curl -X POST --header"Content-Type:application/json" --data ‘{}’ url (使用post模拟json格式请求接口)
curl -I url(仅返回请求头部信息)

header:
POST -d或-F #携带post参数
HEAD -I #携带http文件头
PUT -T #
  • wget
    wget虽然功能强大,但是使用起来还是比较简单的,基本的语法是:wget [参数列表] URL。
wget url     #下载整个http
wget -r url #递归下载

python库

  • urllib
    from urllib import request
    urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应
from urllib import request

with request.urlopen('https://api.douban.com/v2/book/2129650') as f:
data = f.read()
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', data.decode('utf-8'))

可以看到HTTP响应的头和JSON数据:

Status: 200 OK
Server: nginx
Date: Tue, 26 May 2015 10:02:27 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2049
Connection: close
Expires: Sun, 1 Jan 2006 01:00:00 GMT
Pragma: no-cache
Cache-Control: must-revalidate, no-cache, private
X-DAE-Node: pidl1
Data: {"rating":{"max":10,"numRaters":16,"average":"7.4","min":0},"subtitle":"","author":["廖雪峰编著"],"pubdate":"2007-6",...}

​urlparse​​​ python3中urlparse模块和urllib模块合并,urlparse()在urllib.parse中进行调用。
urlparse()把url拆分为6个部分,scheme(协议),netloc(域名),path(路径),params(可选参数),query(连接键值对),fragment(特殊锚),并且以元组形式返回。

from urllib.parse import urlparse
url = 'https://github.com/search?q=krislp'
parse = urlparse(url)
print(parse)

输出结果

ParseResult(scheme='https', netloc='github.com', path='/search', params='', query='q=krislp', fragment='')
  • requests
    它是一个Python第三方库,处理URL资源特别方便。
pip install requests  #安装

使用requests

>>> import requests
>>> r = requests.get('https://www.douban.com/') # 豆瓣首页
>>> r.status_code
200
>>> r.text
r.text
'<!DOCTYPE HTML>\n<html>\n<head>\n<meta name="description" content="提供图书、电影、音乐唱片的推荐、评论和...'

网页解析

python爬取下厨房网站首页图片request+bs4_html_02

  • bs4
    根据标签名进行获取节点
    只能找到第一个符合要求的节点
    获取文本内容和属性
    属性:
    soup.a.attrs 返回一字典,里面是所有属性和值
    soup.a[‘href’] 获取href属性
    文本:
    find:
    soup.find(‘a’)
    soup.find(‘a’, class_=‘xxx’)
    soup.find(‘a’, title=‘xxx’)
    soup.find(‘a’, id=‘xxx’)
    soup.find(‘a’, id=re.compile(r’xxx’))
    find只能找到符合要求的第一个标签,他返回的是一个对象
    find_all
    返回一个列表,列表里面是所有的符合要求的对象
    soup.find_all(‘a’)
    soup.find_all(‘a’, class_=‘wang’)
    soup.find_all(‘a’, id=re.compile(r’xxx’))
    soup.find_all(‘a’, limit=2) 提取出前两个符合要求的a
from bs4 import BeautifulSoup

# 生成soup对象
soup = BeautifulSoup(open('soup.html', encoding='utf8'), 'lxml')
print(type(soup))

print(soup.a.attrs)
print(soup.a.attrs['href'])
print(soup.a['href'])

print(soup.a.string)
print(soup.a.text)
print(soup.a.get_text())

print(soup.div.string)
print(soup.div.text)
print(soup.div.get_text())

ret = soup.find('a')
ret = soup.find('a', title='清明')
ret = soup.find('a', class_='dumu')
print(ret)

import re
ret = soup.find('a', id='xiaoge')
ret = soup.find('a', id=re.compile(r'^x'))
print(ret.string)

ret = soup.find_all('a')
print(ret[1].string)

ret = soup.find_all('a', class_='wang')
print(ret)

ret = soup.find_all('a', id=re.compile(r'^x'))
print(ret)

ret = soup.select('a')
ret = soup.select('#muxiong')
print(ret[0]['title'])

ret = soup.select('.wang')
print(ret)

ret = soup.select('div > a')
print(ret)

ret = soup.select('a[title=东坡肉]')

print(ret)

odiv = soup.select('.tang')[0]

ret = odiv.select('a')

print(ret)

文件操作

读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

  • 读文件
    要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符:
f = open('/Users/michael/test.txt', 'r')

如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示:

>>> f.read()
'Hello, world!'

最后一步是调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:

>>> f.close()
  • 写文件
    你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:
>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

requests.get(url)默认是下载在内存中的,下载完成才存到硬盘上,可以用Response.iter_content 来边下载边存硬盘

import os
from urllib.parse import urlparse
import requests
from bs4 import BeautifulSoup

headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37'}
url='http://www.xiachufang.com/'
r=requests.get(url,headers=headers)
soup=BeautifulSoup(r.text)
# print(r.text)

img_list=[]
for img in soup.select('img'):
# print(img,end='\n\n')
if img.has_attr('data-src'):
# print(img.attrs['data-src'],end='\n\n')
img_list.append(img.attrs['data-src'])
else:
img_list.append(img.attrs['src'])
# print(img.attrs['src'])

img_dir=os.path.join(os.curdir,'images')
if not os.path.isdir(img_dir):
os.mkdir(img_dir)

for img in img_list:
o=urlparse(img)
filename=o.path[1:].split('@')[0]
filepath=os.path.join(img_dir,filename)
print(filename)
img_url='%s://%s/%s'%(o.scheme,o.netloc,filename)
resp=requests.get(img_url,headers=headers)
print(img_url)
with open(filepath,'wb') as f:
for chunk in resp.iter_content(1024):
f.write(chunk)