新手学习Python爬虫之Request和beautifulsoup
Created: Apr 13, 2020 2:45 PM
学了一下爬虫基本原理,利用request和beautiful soup爬了最简单的网页。为了巩固学到的东西,写了一篇总结:
首先,说一下我现在能爬的这些网页的基本特点:
- 在Network中,文档类型为document的请求响应中可以找到需要爬取的所有内容。
- 不需要登陆等POST操作就可以得到需要的信息
这类网页的爬取方法很有规律,变化也不多,总结下来就是这几个步骤:
- 利用request库发送请求,得到响应,即网页源代码
- 利用解析库(我用的是BeautifulSoup)按需解析网页,得到我们需要的信息
- 将信息按照我们需要的格式保存
详细的方法说明
建议配合下方代码一起食用
- 首先打开Network,清空响应,刷新后在Network中找出Type为document的响应,这就是网页源代码
- 点击Headers,复制User-Agent并写在header里(具体操作看下面的代码),告诉网站访问者请求的工具,让网站不会认为我们是在爬虫而是在用浏览器访问。
- 点击Response,在源代码中搜索我们想要找的部分,了解他们对应的DOM结构是怎么样的。(关于DOM的东西不写啦,自己可以搜索)
- 写请求函数,得到网页源代码
- 根据网页源代码和我们需要的信息的DOM结构,按需解析。
放一下代码,再来讲每段代码对应的特色部分:
站酷网批量下载图片
URL:https://www.zcool.com.cn/work/ZNDQzMjAwNjA=.html
我爬取站酷网的起因是站酷网中,有些作品因为作者的版权原因禁止保存。简单的方法是可以通过浏览器审查元素的方式找到相应链接,点开挨个保存,但是这样太麻烦了,就想写一个可以通过输入站酷帖子详情页url的方法快速批量保存。
脚本使用方法: 修改URL链接后运行,就会批量保存图片
使用效果图:
站酷网结构很整齐,所以也很容易找到图片url的位置很容易保存
不足的是,这个是最早写的一份代码,当时对这两个库理解都不深,代码结构写的很差。
from bs4 import BeautifulSoup
import requests
URL = 'https://www.zcool.com.cn/work/ZNDQyNTQ1OTI=.html'
html = requests.get(URL).text
soup = BeautifulSoup(html)
img_ul = soup.find_all('div', {
"class": "reveal-work-wrap"})
print(type(img_ul))
for ul in img_ul:
imgs = ul.find_all('img')
for img in imgs:
url = img['src']
r = requests.get(url,stream='True')
image_name = url.split('/')[-1]
with open('./img/%s' % image_name, 'wb') as f:
for chunk in r.iter_content(chunk_size=128):
f.write(chunk)
print('Saved %s' % image_name)
抓取微博热搜
URL:https://s.weibo.com/top/summary
这个是看到教程里面有教你抓取猫眼电影的,我本来想照着写,奈何猫眼电影现在需要验证码了,我还不太会,所以换了微博热搜来爬
这个脚本没有写输出到文件,简单的输出到控制台先看看效果:
这次写的时候学着更加模块化地定义每个函数,虽然我本人觉得我写C/C++的时候模块化做的还是很好的,但是感觉python是一种很繁华浮躁的脚本语言,所以总是在开始的时候很难静下心来想想怎么模块化。
思路同样很简单,把请求网页写为了一个函数,解析网页写成了一个函数。
在解析网页时,写微博热搜包括后面两段代码时我都遇到了一个问题,就是不知道soup中某些方法在使用过后返回值是什么。我的解决方法是经常使用**type()**函数来查看变量类型。
import requests
from bs4 import BeautifulSoup
def get_one_page(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/80.0.3987.163 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None
def find_hot(html):
soup = BeautifulSoup(html, "html.parser")
hot_text1 = soup.find_all('td')
list = []
for i in hot_text1:
text_all = i.find_all('a', {
&#