0%

爬虫

学习链接

案例:中国旅游网有道翻译

快捷键【Ctrl+U】打开源码页面

合法性:如果网站有 robots.txt 文档,要判断是否有禁止访客获取的数据。

准备工作:在 PyCharm 中安装 requests 库

基本原理:网页请求分为request和response两个环节,request分get和post两种方式,写爬虫前要先确定向谁发送请求,用什么方式发送。

开始爬虫

所有在源码中的数据请求方式都是GET

1
2
3
4
import requests        #导入requests包
url = 'http://www.cntour.cn/'
strhtml = requests.get(url) #Get方式获取网页数据
print(strhtml.text)

用 GET 方式获取数据需要调用 requests 库中的 get 方法:requests.get(url),这个方法获得一个url对象,代表整个网页,如果只需网页中的源码,使用.text

在开发者模式中,依次单击“Network”按钮和“XHR”按钮,找到翻译数据,将 Headers 中的 URL 复制出来,并赋值给 url。POST 请求数据必须构建请求头。复制From Data中的请求参数并构建一个新字典。使用 requests.post 方法请求表单数据。将字符串格式的数据转换成 JSON 格式数据,并根据数据结构,提取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests        #导入requests包
import json
def get_translate_date(word=None):
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
From_data={'i':word,'from':'zh-CHS','to':'en','smartresult':'dict','client':'fanyideskweb','salt':'15477056211258','sign':'b3589f32c38bc9e3876a570b8a992604','ts':'1547705621125','bv':'b33a2f3f9d09bde064c9275bcb33d94e','doctype':'json','version':'2.1','keyfrom':'fanyi.web','action':'FY_BY_REALTIME','typoResult':'false'}
#请求表单数据
response = requests.post(url,data=From_data)
#将Json格式字符串转字典
content = json.loads(response.text)
print(content)
#打印翻译后的数据
#print(content['translateResult'][0][0]['tgt'])
if __name__=='__main__':
get_translate_date('我爱中国')

POST请求有道翻译{“errorcode:50}——把URL中把_o去掉

json模块主要有四个比较重要的函数,分别是:

  • dump - 将Python对象按照JSON格式序列化到文件中
  • dumps - 将Python对象处理成JSON格式的字符串
  • load - 将文件中的JSON数据反序列化成对象
  • loads - 将字符串的内容反序列化成Python对象

Beautiful Soup 解析网页

安装 bs4 库,安装 lxml 库

1
2
3
4
5
6
7
import requests        #导入requests包
from bs4 import BeautifulSoup
url='http://www.cntour.cn/'
strhtml=requests.get(url)
soup=BeautifulSoup(strhtml.text,'lxml')
data = soup.select('#main>div>div.mtop.firstMod.clearfix>div.centerBox>ul.newsList>li>a')
print(data)

首先,HTML 文档将被转换成 Unicode 编码格式,然后 Beautiful Soup 选择最合适的解析器来解析这段文档,此处指定 lxml 解析器进行解析。解析后便将复杂的 HTML 文档转换成树形结构,并且每个节点都是 Python 对象。将解析后的文档存储到新建的变量 soup 中。用 select(选择器)定位数据,方法:开发者模式,将鼠标光标停留在对应的数据位置并右击,“Copy”➔“Copy Selector”,使用 soup.select 引用这个路径。

清洗和组织数据

1
2
3
4
5
6
for item in data:
result={
'title':item.get_text(),
'link':item.get('href')
}
print(result)

标题在<a>标签中,提取标签的正文用 get_text() 方法。链接在<a>标签的 href 属性中,提取标签中的 href 属性用 get() 方法,在括号中指定要提取的属性数据,即 get('href'),用正则表达式提取 ID (re库中)

1
2
3
4
5
6
7
8
import re
for item in data:
result={
"title":item.get_text(),
"link":item.get('href'),
'ID':re.findall('\d+',item.get('href'))
}
print(result)

\d匹配数字,+匹配前一个字符1次或多次。 re 库的 findall 方法,第一个参数表示正则表达式,第二个参数表示要提取的文本

re.compile(r’^/question’)是正则表达式 匹配 ‘/question’开头

应对反爬虫

在 Request headers 中构造浏览器的请求头,封装自己。服务器识别浏览器访问的方法就是判断 keyword 是否为 Request headers 下的 User-Agent

………………


关于json编码:

1
2
3
4
5
import json
obj = {"name": "测试"}
json.dumps(obj)
print(json.dumps(obj))
print(json.dumps(obj, ensure_ascii=False))

输出结果:

1
2
{"name": "\u6d4b\u8bd5"}
{"name": "测试"}