获取URL
获取HTML
解析HTML
获取URL
首先要知道URL是什么:
URL: Uniform Resource Identifier,即统一资源标识符。
URL: Uniform Resource Locator,即统一资源定位符。
平常基本用的都是URL,平常访问的网址链接都可以理解为URL。 例如https://www.baidu.com,就是你想要去访问的网页。当然你要访问的更详细的,例如本文的知乎热榜:https://www.zhihu.com/hot
获取HTML
HTML称为超文本标记语言,是一种标识性的语言。也就是访问网页得到的数据,都存放在HTML中,CSS,JS可以去了解一下。
有了URL,直接用python取访问是可能会被封IP的,所以就要用python来模拟浏览器取访问这些网页,这时就需要用到user-agent和cookie。user-agent存放的是浏览器的版本,cookie用来保持登陆之后连续访问多次网站而不需要反复登录。邮件检查或者是f12,在Network选项卡下面的众多记录中随便点进去,找到user-agent和cookie,
后面需要的时候复制下来(cookie是经常更新的)。
原材料就足够了,现在需要进行烹饪了。
requests
通过以上的原材料来获取HTML,就需要用到 requests 包
pip install requests
安装成功后就可以进行编码了。
import requests
url = 'https://www.zhihu.com/hot'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36',
'cookie':"""cookie要用自己的并且经常要更新"""
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
html = response.text
print(html)
首先要将之前的原料放到一个名为headers的字典里面,然后通过requests 的 get() 函数来获取到URL的内容。通过if语句来判断访问是否成功,状态码为200代表访问成功。但是访问返回的数据是HTML类型的,通过 .text 转化为文本格式。这样就获得了知乎热榜的内容,仔细观察就能看到热榜的问题在此之中,然后下一步就可以进行内容的提取了。
解析HTML
此次的解析库我使用的是较为普遍的 XPath,稍后有时间再更新其他方法。
XPath 提供了非常简洁明了的路径选择表达式,超过100个内建函数,几乎可以定位所有想要的节点。
基础的XPath常用规则:
表达式
描述
nodename
选取此节点的所有子节点
/
从当前节点选取直接子节点
//
从当前节点选取子孙节点
.
选取当前节点
…
选取当前节点的父节点
@
选取属性
示例如下:
//title[@lang='eng']
这就是一个XPath规则,代表选择所有名称为title,同时属性lang的值为eng 的节点。
后面会通过python的lxml库,利用XPath进行HTML解析。
准备工作
pip install lxml
就这篇博客的目的来讲,这里只说一下获取知乎热榜的问题所需要的东西。仔细观察之前获取到的HTML,然后就会发现,知乎热榜的问题,都存放在h2。这里建议从开发者模式中依次寻找,找到对应的标题所对应的具体的HTML,因为一个标题会对应很多的相同的字符,在HTML中,这里我找到的实在 h2 中(后续知乎可能会更新,我看过很多的代码,再次自己实现,就会有很多问题,找不到之类的,建议自己实际再找一遍)。
然后就可以根据自己需要的节点来进行定位,获取数据。
首先要进行的准备工作就是:
from lxml import etree
这里先导入lxml库的etree模块,然后调用HTML类进行初始化,这样就构造了一个XPath解析对象,etree 可以自动修正HTML,比如某些节点没有闭合。但是调用tostring之后输出的修正后的HTML代码,结果是bytes类型的,这里可以利用decode()方法将其转化为str类型。示例如下:
from lxml import etree
html = etree.HTML(html)
result = etree.tostring(html)
print(result.decode('utf-8'))
results = html.xpath('//h2/text()')
这里就可以得到知乎热榜的问题了。
当然,可以遍历输出,之后的就是字符串操作的范畴了。
附完整代码:
import requests
from pyquery import PyQuery as pq
from lxml import etree
url = 'https://www.zhihu.com/hot'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36',
'cookie':"""写自己的,很重要"""
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
html = response.text
print(html)
html = etree.HTML(html)
result = etree.tostring(html)
print(result.decode('utf-8'))
results = html.xpath('//h2/text()')
count = 0
for result in results:
print(result)
count += 1
print(count)
有关解析库XPath的学习可以参考我的另一篇文章:XPath解析库的学习。
2019.10.21更新
对于之前获取到的知乎热榜的问题,我又进行了下一步的更新,这次更新的结果是,将知乎热榜的内容进行了全部爬取,爬取过程变得简单,但是由于个人比较愚笨,花了较长时间对内容进行了优化,结果是将50个问题按照每个问题为划分,一个问题为一个列表,50个问题又组成了一个列表,以便后续的数据分析,结果展示:
[[问题1],[问题2],[问题3],[问题4],[问题5],[问题6]...]
另外我将函数进行了封装,阅读性更强。
由于知乎热榜的每个问题的内容不同,有的有问题简介,有的没有,所以比较乱,当然可以按照其他方式进行分割,我这里使用的是索引方式。(提示:我这里爬取到的结果每个问题都是不同的,但是每个问题开头都是数字,结尾都是“分享”,可以从这里入手,但是我试了几次失败了,如果哪位大神解决了这个问题,可以给我一些建议。
获取网页内容
获取索引
处理结果
我分为了以上三部分,总结代码如下:
# -*- coding: utf-8 -*-
# @Time : 2019-10-11 9:35
# @Author : Ru
import requests
from lxml import etree
def get_content(url,headers):
"""
根据url,headers来获取网页内容
:param url:
:param headers:
:return:content
"""
response = requests.get(url,headers=headers)
if response.status_code == 200:
html = response.text
html = etree.HTML(html)
content = html.xpath('//section//text()')
return content
def get_index(content):
"""
获取索引
:param content:
:return:index_list
"""
index_list = []
for i in range(1,51):
i = str(i)
index_list.append(content.index(i))
return index_list
def return_result(content,index_list):
"""
处理结果
:param content:
:param index_list:
:return:result
"""
result = []
for num in range(60):
#60是因为循环的次数要大于50或者是51,具体哪个我也不清楚,就索性60简单些
for i in range(len(index_list)):
pri_lsit = []
a = index_list[i]
if index_list[i] == index_list[-1]:
b = len(content)
else:
b = index_list[i + 1]
for i in range(a, b):
pri_lsit.append(content[i])
# print(pri_lsit)
result.append(pri_lsit)
print(result)
return result
if __name__ == '__main__':
url = 'https://www.zhihu.com/hot'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36',
'cookie': """还是注意一点,cookie要用自己的,这一点很重要"""
}
content = get_content(url,headers)
index_list = get_index(content)
return_result(content,index_list)
结果展示: