【python实现网络爬虫(3)】最简单的网络爬虫(笑话大全网冷笑话标题爬取)

爬取笑话网

笑话大全网址,找到笑话分类,选择冷笑话
在这里插入图片描述

窥探网页细节

步骤一、观察翻页之后URL的变化
第一页的URL:http://xiaohua.zol.com.cn/lengxiaohua/
第二页的URL:http://xiaohua.zol.com.cn/lengxiaohua/2.html
第三页的URL:http://xiaohua.zol.com.cn/lengxiaohua/3.html
......

看到这里就可以找出里面的规律, 第一页的话URL应该是http://xiaohua.zol.com.cn/lengxiaohua/1.html,不妨把这个网址输入,验证一下,结果正是对应了上面的规律

步骤二、推荐使用浏览器为Chrome(谷歌)

主要是插件丰富,原生功能设计对爬虫开发者非常友好
在这里插入图片描述

步骤三、获取页面内容

利用requests输出首页内容,要先安装requests库

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple

安装成功后,运行代码如下

import requests

headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}

html = requests.get('http://xiaohua.zol.com.cn/lengxiaohua/1.html',headers = headers)

print(html.text)

–> 输出结果为:
在这里插入图片描述
headers就是请求头,可以通过打开一个浏览器,然后网页空白处右键选择“检查”,点击Network,然后刷新一下页面,这时候选择右侧出现的第一条信息,往下拉就可以获得headers了,如下
在这里插入图片描述
如果要获取第二页的内容,直接将网址(URL)修改一下,将里面的数字1,变成数字2,因此要爬取多页的消化信息时,就可以构造一个url循环就可以了,比如获取前十页的笑话信息,代码如下

for i in range(10):
	html = requests.get('http://xiaohua.zol.com.cn/lengxiaohua/{}.html'.format(i+1),
		headers = header
	print(html.text)

–> 输出结果为: 类似输出一页的结果样式,输出的是十页的结果

页面源代码

我们print输出的正是html的内容,可以通过浏览器,在目标页面点击鼠标右键,选择“查看网页源代码(Ctrl + U)”,如下
在这里插入图片描述
其中网址最前面的:view-source就是查看源代码的意思

分析网页源代码

就以刚刚获得的笑话大全中冷笑话页面的源代码为例
在这里插入图片描述
其中:
lang = “zh-CN” (lang就是language的缩写代表语言; “zh-CN”,其中zh就是中文的意思,CN代表着中国)

charset = “utf-8/gbk” 代表着字符集的编码形式,其中gbk编码里面已经包含了很多的汉字了

学会“一一对应”的观察技巧

我们日常可以看到的页面内容
在这里插入图片描述
源代码中对应的内容(按住ctrl + f 进行相关字词的查找)
在这里插入图片描述

明确任务

通过检查,可以发现每一个笑话都包含在<<li class="article-summary>>里面
在这里插入图片描述

BeautifulSoup

解析网页的强力工具,爬虫利器,安装(顺带把lxml库安装)和如何使用的代码如下,关于“lxml”的知识,我会在《爬虫专项》里面介绍这里就不再进行详细说明了

pip install bs4 lxml -i https://pypi.tuna.tsinghua.edu.cn/simple #安装代码
from bs4 import BeautifulSoup  #库的使用
Tag标签

Tag就是HTML中的一个个标签,但是需要注意,这里只会返回第一个符合要求的标签(即使HTML中有多个符合要求的标签),用代码解释一下

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/75.0.3770.100 Safari/537.36"}

r = requests.get("http://xiaohua.zol.com.cn/lengxiaohua/1.html", headers = headers)
html = r.text
soup = BeautifulSoup(html, "lxml")
#print(soup.prettify())
print('***title***')
print(soup.title)
print('\n***head***')
print(soup.head)
print("\n***a***")
print(soup.a)
print("\n***p***")
print(soup.p)

–> 输出结果为: 只会输出一个title、head、a和p标签

***title***
<title>【冷笑话】2020冷笑话大全-ZOL笑话频道</title>

***head***
<head>
<meta charset="utf-8"/>
<meta content="pc" name="applicable-device"/>
<title>【冷笑话】2020冷笑话大全-ZOL笑话频道</title>
<meta content="冷笑话,冷笑话大全,2020冷笑话" name="keywords"/>
<meta content="ZOL笑话频道为您提供各种冷笑话,最新最经典的冷笑话,海量的冷笑话尽在ZOL笑话频道,让您一览无余" name="description"/><link href="//s.zol-img.com.cn/d/Xiaohua/Xiaohua_List.css?v=686" rel="stylesheet" type="text/css"/>
<meta content="format=html5; url=//m.zol.com.cn/xiaohua/lengxiaohua/1.html" http-equiv="mobile-agent"/>
<script>
        var nA = navigator.userAgent;
        ios = /iPhone|iPod|iTouch/i.test(nA);
        android = /android/i.test(nA);
        if(window.location.href.indexOf("?via=")<0){
            if(ios || android){
                self.location='//m.zol.com.cn/xiaohua'+location.pathname;
            }
        }
</script>
<script src="//p.zol-img.com.cn/xiaohua/list.js" type="text/javascript"></script>
<style>
    .guanggao{
    line-height: 30px;
    margin: 10px 0 0;
    padding: 10px 0 10px 10px;
   } 
   .guangao{
    margin: 11px 0 0;
    padding: 0 20px 30px 15px;
    position: relative;
    }
</style>
</head>

***a***
<a class="logo" href="/">
<img alt="ZOL笑话大全" height="32" src="//icon.zol-img.com.cn/mainpage/2019logo/logo-xiaohua.png" width="214"/>
</a>

***p***
<p>

		1、火云邪神苦练多年,终于将蛤蟆功练至顶级并成功产下8个小蝌蚪。

	</p>
[Finished in 0.6s]
soup.prettify() 标准打印输出
soup.title 输出第一个满足的title标签
soup.head 输出第一个满足的head标签
soup.a 输出第一个满足的a标签
soup.p 输出第一个满足的p标签
.find_all()查找全部的标签

如果想找到全部的Tag(标签),需要使用.find_all方法,就刻意获得当前Tag的所有子节点,并判断是否符合过滤器的条件,举个栗子,获取所有的p标签

print(soup.find_all("p"))

–> 输出结果为: 只截取部分输出
在这里插入图片描述

keyward参数

这个参数不是该函数内置的函数名,而是对应的想要搜索的关键字的名字,比如

<a accesskey="I" href="genindex.html" title="General Index">insex</a>
print(soup.find_all(accesskey="I"))

CSS选择器

★★★★★ soup.select()和soup.find_all()方式是等价的,两者返回的都是列表,举例如下

soup.select('title')
soup.find_all('title')

soup.select('a')
soup.find_all('a')

soup.select('.footer')
soup.find_all(True, class_ = 'footer')

soup.select('p #link')
soup.find_all('p', id = 'link')

soup.select('head > title')
soup.head.find_all('title')

soup.select('a[href="www.baidu.com"]')
soup.find_all('a', href='www.baidu.com')

CSS选择器的语法规则

四大标签名不需要加任何修饰 [title、head、a、p]

class名前要加点

id名前要加#

举个栗子如下,在浏览器检查页面按住ctrl + f进入查找界面,输入“.article-summary”,就可以找到笑话对应的标签了
在这里插入图片描述

如果p标签里面有class

<p class="para">这是一个p标签</p>

如果标签内容如上所述,CSS选择器的搜索方式就是:p.class(p可以省略)

<p class="para tag">这是第二个p标签</p>

如果标签内容如上所述,CSS选择器的搜索方式就是:p.para.class(p可以省略)

<p class="para tag">
		<p>这是第二个p标签</p>
</p>

如果标签内容如上所述,CSS选择器的搜索方式就是:

①若是里面的p标签下还有标签,也就是里面还有子孙辈的p标签,要获取里面所有的标签(子孙)可以使用p.para.tag p

②若是里面的p标签下还有标签,也就是里面还有子孙辈的p标签,只获得第一层里面的标签(子)可以使用p.para.tag>p

如果p标签里面有id

因为id是唯一的,所以当要选择id对应的标签时候,就可以省略一切都不看,直接#xx就可以了,举个例子如下

<p class="para">这是一个p标签</p>
<p class="para tag">
		<p id='only_tag'>这是第二个p标签</p>
</p>

要想获得里面的id所在的标签内容,直接使用:#only_tag

在div中标签可以省略,直接通过class和id进行定位

<div class="test">
	<p class="para tag">
		<p id='only_tag'>这是第二个p标签</p>
	</p>
</div>

比如选择最里层的标签:.test.para p(这种方式在实战解析里面也有用到)

实战解析

步骤一、建立for循环爬取前10页的内容

for i in range(10):
	html = requests.get('http://xiaohua.zol.com.cn/lengxiaohua/{}.html'.format(i+1),
		headers = headers)
	print(html.text)

这里的输出结果和上面的一样

步骤二、通过CSS选择器找到每条内容

这一步,上面有详细介绍,下面给图就行了
在这里插入图片描述

步骤三、找到每条标签里面的内容并输出

每个笑话的标题都是在.article-summary标签下的.article-title标签下面

soup = BeautifulSoup(html.text,'lxml')
	for joke in soup.select('li.article-summary'):
		title = joke.select('.article-title')[0].text
		print(title)

–> 输出结果为:只截取了部分,可见第二个就是我们上面选取的示例的标题
在这里插入图片描述

全部代码

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/75.0.3770.100 Safari/537.36"}

for i in range(10):
	html = requests.get('http://xiaohua.zol.com.cn/lengxiaohua/{}.html'.format(i+1),
		headers = headers)
	soup = BeautifulSoup(html.text,'lxml')
	for joke in soup.select('li.article-summary'):
		title = joke.select('.article-title')[0].text
		print(title)
发布了37 篇原创文章 · 获赞 10 · 访问量 4162

猜你喜欢

转载自blog.csdn.net/lys_828/article/details/104153786