文章目录
1、文章说明
声明:本文爬虫的内容是人民网首页的8张自动轮播图,如果发现本人有侵权行为,在下方留言
概述:本文将学习urlopen
、BeautifulSoup
、urlretrieve
三个方法,学习后会在人民网首页爬取8张图片,并下载到本地
tips:如果你想要先看运行结果,请直接跳到第3部分
2、方法解析
2.1、urlopen
先来看看官方的解释
'''Open the URL url, which can be either a string or a Request object.'''
嗯,很容易理解,只要是个能打开的url
就行,urlopen
能够打开一个url
,然后获得文本内容,我们可以通过read
方法来读出内容
from urllib.request import urlopen
html = urlopen("http://www.people.com.cn/")
html.read() # 返回的内容就跟我们平时写的html页面基本一样的
2.2、BeautifulSoup
官方解释
"""A data structure representing a parsed HTML or XML document."""
就是说,正常情况下,我们通过urlopen().read()
读取出的数据是一段长文本数据,并不能够直接进行处理,而经过BeautifulSoup
处理后,我们就能够像字典一样处理网站的元素,而BeautifulSoup
本身也带有譬如find
、findAll
的方法来方便开发者处理html数据
from bs4 import BeautifulSoup as bf
obj = bf(html.read(), "html.parser")
imgs = obj.findAll("img")
for img in imgs:
print(img["src"])
2.3、urlretrieve
官方解释
"""Retrieve a URL into a temporary location on disk."""
就是说,把一个url
里面的内容存到你的本地磁盘里去
from urllib.request import urlretrieve
urlretrieve(url, pathname)
3、所有代码
前提:你需要在根目录创建imgs
文件夹
from urllib.request import urlopen, urlretrieve
from bs4 import BeautifulSoup as bf
html = urlopen("http://www.people.com.cn/")
obj = bf(html.read(), "html.parser")
swiper = obj.find("div", {"class": "swiper-container-p1"})
imgs = swiper.findAll("img")
baseurl = "http://www.people.com.cn"
for i, img in enumerate(imgs):
url = baseurl + img["src"]
print(url)
urlretrieve(url, f"./imgs/swiper-{i}.jpg")
以上代码可以存储到index.py
文件中,然后在终端运行python index.py
,稍等片刻就能在imgs文件夹中查看爬取到的图片啦
4、可能会遇到的坑
当然,如果你想要爬取的内容是被简单限制了的,你就会发现urlopen
之后会报error 403
的错误。这个时候,你需要让python学聪明一点,让它伪装
成一个浏览器。我们可以通过以下代码来实现:
4.1、urlopen 出现403的解决方法
from urllib import request
"""
headers的信息,
User-Agent就是在说明我是在用什么设备进行访问的。
你同样可以按F12,打开浏览器,
在Network里面点击任意一个请求,
查看里面的Request Headers,
那里就有写上你本机的User-Agent
"""
url = "你想要爬取的url"
headers = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
req = request.Request(url=url, headers=headers)
request.urlopen(req)
如果需要爬取文本,则使用BeautifulSoup().text
就能获取到文本啦~
4.2、urlretrieve 出现403的解决方法
同样的,如果urlretrieve
出现了403的情况,那么加个请求头也同样可以解决这个问题。然而,urlretrieve
本身没有headers
这个参数可以加,所以我们需要在request
本身install
一个headers
,代码如下:
from urllib import request
opener = request.build_opener()
opener.addheaders = [("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36")]
request.install_opener(opener)
request.urlretrieve(url, Path)
4.3、urlretrieve 出现卡死问题,怎么办?
额,终于解决了,大部分卡死问题,都能够解决:
我们经常卡死的地方是urlopen和urlretrieve,一般都是因为超时请求或者部分细节原因有冲突导致,如果你正在爬取,但经常爬取到一般就失败,不妨试试以下方法:
使用迭代来解决报错的问题,因为try···catch···只会执行一次,然后下次会消失,所以不能使用for循环,我们使用函数来反复触发try···catch···就能解决啦~
from urllib.request import urlopen, urlretrieve
def _urlopen(url):
try:
res = urlopen(url)
except Exception:
print("_urlopen is trying again")
return _urlopen(url)
return res
def _urlretrieve(url, filename):
try:
urlretrieve(url, filename)
except Exception:
print("_urlretrieve is trying again")
return _urlretrieve(url, filename)
return True
4.4、url里带有中文路径怎么办?
比如往一个网站发送一个get
请求,在JavaScript
里写就是{ key: value }
就搞定了,其中的value
就能够是中文,但url里不能有中文,所以需要转码,那python
如何转码呢?使用quote
就可以啦~
from urllib.parse import quote
my_gbk = "中文内容"
print(quote(my_gbk))
有问题或者有参考都会写到这篇文章里
持续更新中……