HTTP
HTTP是一个客户端和服务器端之间进行请求和应答的标准。
HTTP请求方法主要包括以下几个:
- GET
- HEAD
- POST
- PUT
- DELETE
- TRACE
- OPTIONS
- CONNECT
网页基础
网页组成
网页由HTML、CSS、JavaScript组成。
HTML是用来搭建整个网页的骨架
CSS是为了让整个页面更好看,比如控制颜色,大小,位置等
JavaScript是用来让网页‘动起来’。(1.网页数据动态交互,2.动画显示配合CSS)
HTML通过浏览器按F12查看。
选项Elements中可以看到HTML源代码
图片用 <img> 标签表示,视频用 <video> 标签表示,段落用 <p> 标签表示,它们之间的布局又常通过布局标签 <div> 嵌套组合而成,各种标签通过不同的排列和嵌套才形成了网页的框架.
网页结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h1>Hello World</h1>
<div>Hello Python.</div>
</div>
</div>
</body>
</html>
整个文档是以 DOCTYPE 来开头的,这里定义了文档类型是 html ,整个文档最外层的标签是 ,并且结尾还以 </html> 来表示闭和。
整个 HTML 文档一般分为 head 和 body 两个部分,在 head 头中,我们一般会指定当前的编码格式为 UTF-8 ,并且使用 title 来定义网页的标题,这个会显示在浏览器的标签上面。
body 中的内容一般为整个 html 文档的正文,html的标签由<h1>到<h6>六个标签构成,字体由大到小递减,换行标签为<br>,链接使用<a>来创建,herf属性包含链接的URL地址
-
id
属性为元素提供在全文档内的唯一标识。它用于识别元素,以便样式表可以改变其外观属性,脚本可以改变、显示或删除其内容或格式化。对于添加到页面的url,它为元素提供了一个全局唯一识别,通常为页面的子章节。 -
class
属性提供了一种将类似元素分类的方式,常被用于语义化或格式化。例如,一个html文档可以指定class="标记"来表明所有具有这一类值得元素都属于文档的主文本。格式化后,这样的元素可能会聚集在一起,并作为页面脚注而不会出现在html代码中。类值也可以多值声明。如class="标记
重要"将元素同时放入“标记”与“重要”两类中。 -
style 属性可以将表现性质赋予一个特定原色。比起使用id或class属性从样式表中选择元素,“style”被认为是一个更好的做法。
-
tile 属性用于给元素一个附加的说明。大多数浏览器中这一属性显示为工具提示。
HTML DOM
HTML DOM 将 HTML 文档视作树结构。这种结构被称为节点树:
下面的图片展示了节点树的一部分,以及节点之间的关系:
使用开发者工具检查网页
选择“菜单”中的“更多工具” → “开发者工具”,也可以直接在网页内容中右击并选择“检查”选项,还可以按f12键。效果如下图所示。
Chrome的开发者模式为用户提供了下面几组工具。
-
Elements:允许用户从浏览器的角度来观察网页,用户可以借此看到Chrome渲染页面所需要的HTML、CSS和DOM(Document Object Model)对象。
-
Network:可以看到网页向服务气请求了哪些资源、资源的大小以及加载资源的相关信息。此外,还可以查看HTTP的请求头、返回内容等。
-
Source:即源代码面板,主要用来调试JavaScript。
-
Console:即控制台面板,可以显示各种警告与错误信息。在开发期间,可以使用控制台面板记录诊断信息,或者使用它作为shell在页面上与JavaScript交互。
-
Performance:使用这个模块可以记录和查看网站生命周期内发生的各种事情来提高页面运行时的性能。
-
Memory:这个面板可以提供比Performance更多的信息,比如跟踪内存泄漏。
-
Application:检查加载的所有资源。
-
Security:即安全面板,可以用来处理证书问题等。
另外,通过切换设备模式可以观察网页在不同设备上的显示效果,快捷键为:Ctrl + Shift + M(或者在 Mac上使用 Cmd + Shift + M)
值得注意的是右键菜单中的“Copy XPath”选项。由于XPath是解析网页的利器,因此Chrome中的这个功能对于爬虫程序编写而言就显得十分实用和方便了。
使用“Network”工具可以清楚地查看网页加载网络资源地过程和相关信息。请求的每个资源在“Network”表格中显示为一行,对于某个特定的网络请求,可以进一步查看请求头、响应头及已经返回的内容等信息。对于需要填写并发送表单的网页而言(比如执行用户登录操作,以百度贴吧为例),在“Network”面板勾选“Preserve log”复选框,然后进行登录,就可以记录HTTP POST信息,查看发送的表单信息详情。之后在贴吧首页开启开发者工具后再登录时,就可以看到下图所示的信息,其中“Form Data”就包含向服务器发送的表单信息详情。
另外“Network”中的“Preview”也是比较常用,可以用来预览数据。
一个网络爬虫程序最普遍的过程:
- 访问站点;
- 定位所需的信息;
- 得到并处理信息。
example
利用金山词霸来翻译爬出来的python之禅
import requests
url = 'https://www.python.org/dev/peps/pep-0020/'
res = requests.get(url)
text = res.text
text
## 爬取python之禅并存入txt文件
with open('zon_of_python.txt', 'w') as f:
f.write(text[text.find('<pre')+28:text.find('</pre>')-1])
print(text[text.find('<pre')+28:text.find('</pre>')-1])
import requests
def translate(word):
url="http://fy.iciba.com/ajax.php?a=fy"
data={
'f': 'auto',
't': 'auto',
'w': word,
}
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
}#User-Agent会告诉网站服务器,访问者是通过什么工具来请求的,如果是爬虫请求,一般会拒绝,如果是用户浏览器,就会应答。
response = requests.post(url,data=data,headers=headers) #发起请求
json_data=response.json() #获取json数据
print(json_data)
return json_data
def run(word):
result = translate(word)['content']['out']
# print(result)
return result
def main():
with open('zon_of_python.txt') as f:
zh = [run(word) for word in f]
with open('zon_of_python_zh-CN.txt', 'w') as g:
for i in zh:
g.write(i + '\n')
if __name__ == '__main__':
main()
实战 爬取豆瓣电影
我的代码
import requests
def findmovies():
url = 'https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&page_limit=50&page_start=0'
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'}#User-Agent会告诉网站服务器,访问者是通过什么工具来请求的,如果是爬虫请求,一般会拒绝,如果是用户浏览器,就会应答。
response = requests.get(url,headers = headers)
return response.text
res = findmovies()
movies = res[res.find('{"rate'):-2]
mov = movies.split('},{')
ans = []
for movie in mov:
title = movie[movie.find('"title":')+9:movie.find('","url')]
img = movie[movie.find('"cover":"')+9:movie.find('","id":')]
ans.append((title,img))
print(ans)
结果图片
官方代码:
import requests
import os
if not os.path.exists('image'):
os.mkdir('image')
def parse_html(url):
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'}#User-Agent会告诉网站服务器,访问者是通过什么工具来请求的,如果是爬虫请求,一般会拒绝,如果是用户浏览器,就会应答。
response = requests.get(url,headers = headers)
text = response.text
item = []
for i in range(25):
text = text[text.find('alt')+3:]
item.append(extract(text))
return item
def extract(text):
text = text.split('"')
name = text[1]
img = text[3]
return name,img
def write_movie_film(item,stars):
print(item)
with open('douban_film.txt','a',encoding = 'utf-8') as f:
f.write('排名:%d\t电影名:%s\n' % (stars,item[0]))
r = requests.get(item[1])
with open('image/' + str(item[0]) + '.jpg','wb') as f:
f.write(r.content)
def main():
star = 1
for offset in range(0,250,25):
url = 'https://movie.douban.com/top250?start=' + str(offset) +'&filter='
for item in parse_html(url):
write_movie_film(item,star)
star += 1
if __name__ == '__main__':
main()
使用API
API使用示例
下面以百度地图提供的API为例,首先我们打开链接:http://lbsyun.baidu.com/apiconsole/key 填写自己的信息
首先我们创建一个html文件,例如test.html,复制下面代码,输入自己的AK
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
body,
html,
#allmap {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
font-family: "微软雅黑";
}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=70QMStXzfIvzUHphtObY73MxaQDjXsY2"></script> //在 ak=后面输入你的ak
<title>地图展示</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
// 百度地图API功能
var map = new BMap.Map("allmap"); // 创建Map实例
map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 初始化地图,设置中心点坐标和地图级别
//添加地图类型控件
map.addControl(new BMap.MapTypeControl({
mapTypes: [
BMAP_NORMAL_MAP,
BMAP_HYBRID_MAP
]
}));
map.setCurrentCity("北京"); // 设置地图显示的城市 此项是必须设置的
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
</script>
然后用Chrome打开这个文件,效果如下图所示:
当然,百度地图api还有很多作用,关于百度地图API的其他使用,其官方文档说的非常详细和清楚 http://lbsyun.baidu.com/index.php?title=jspopular3.0 ,但是调用更复杂的功能需要有一定的网页基础。下面我们介绍如何实现地理编码功能
import requests
def getUrl(*address):
ak = '70QMStXzfIvzUHphtObY73MxaQDjXsY2' ## 填入你的api key
if len(address) < 1:
return None
else:
for add in address:
url = 'http://api.map.baidu.com/geocoding/v3/?address={0}&output=json&ak={1}'.format(add,ak)
yield url
def getPosition(url):
'''返回经纬度信息'''
res = requests.get(url)
#print(res.text)
json_data = eval(res.text)
if json_data['status'] == 0:
lat = json_data['result']['location']['lat'] #纬度
lng = json_data['result']['location']['lng'] #经度
else:
print("Error output!")
return json_data['status']
return lat,lng
if __name__ == "__main__":
address = ['北京市清华大学','北京市北京大学','保定市华北电力大学','上海市复旦大学','武汉市武汉大学']
for add in address:
add_url = list(getUrl(add))[0]
print('url:', add_url)
try:
lat,lng = getPosition(add_url)
print("{0}|经度:{1}|纬度:{2}.".format(add,lng,lat))
except Error as e:
print(e)