2.1 关于爬虫的合法性
- 几乎每一个网站都有一个名为robots.txt的文档,用来判断是否有禁止访客获取的数据,以淘宝为例子,在浏览器访问 https://www.taobao.com/robots.txt,淘宝允许部分爬虫访问它的部分路径,而对于没有得到允许的用户则是全部禁止爬取,代码如下:
# 除前面指定的爬虫外,不允许其他爬虫爬取任何数据。
User-Agent: *
Disallow: /
2.2 认识网页结构
- 网页由HTML(超文本标记语言)、CSS(层叠样式表)、JScript(活动脚本语言)三部分组成。
2.3 使用GET方式抓取数据
- Ctrl+U 打开源码页面,Ctrl+F打开搜索框,确认好请求对象和方式后,在pycharm中输入以下代码。
import requests #导入requests包
url = 'http://www.cntour.cn/'
strhtml = requests.get(url) #GET方式,获取网页数据
print(strhtml.text) #表示网页源代码
2.4 使用POST抓取数据
- 以有道翻译为例,首先输入网址:http://fanyi.youdao.com/,按F12,进入开发者模式依次单击“Network”按钮和“XHR”按钮,找到翻译数据。
import requests
import json
def get_translate_data (word=None):
url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule '
Form_data = {'i': word,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': '15629866146500',
'sign': '3980757ebe914c2d22649888361da473',
'ts': '1562986614650',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME',
'typoResult':'false'}
response = requests.post(url,data = Form_data)
content = json.loads(response.text)
print(content['translateResult'][0][0]['tgt'])
if __name__ =='__main__':
get_translate_data ('我爱数据')
2.5 使用 Beautiful Soup 解析网页
- 首先安装BeautifuSoup4,然后还需要安装lxml库,如果不安装,就会使用python默认的解析器,安装完python第三方库之后,输入以下代码:
import requests
import pprint
from bs4 import BeautifulSoup
url = 'http://www.cntour.cn/'
strhtml = requests.get(url)
soup = BeautifulSoup(strhtml.text,'lxml') # 指定lxml解析器进行解析
data = soup.select('#main > div > div.mtop.firstMod.clearfix > div.leftBox > div:nth-child(2) > ul > li > a')
pprint.pprint(data)
- 在浏览器的开发者模式,对爬取内容的路径进行Copy selector,代码如下:
#main > div > div.mtop.firstMod.clearfix > div.leftBox > div:nth-child(2) > ul > li > a
2.6 数据清洗
for item in data:
result={
'title':item.get_text(),
'link':item.get('href')
}
print(result)
- 正则表达式,提取链接中的数字ID,需要用到的正则符号如下:
\d #匹配数字
+ #匹配前一个字符1次或多次
- 在python中调用正则表达式时使用re库,这个库不用安装,可以直接调用,在pycharm中输入以下代码:
import re
for item in data:
result = {
'title':item.get_text(),
'link':item.get('href'),
'ID':re.findall('\d+',item.get('href'))
}
- 这里使用re库的finadall方法,第一个参数表示正则表达式,第二个参数表示要提取的文本。
2.6 爬虫攻防线
- 网站针对爬虫,会采取一些反爬策略,第一种方式就是通过检查链接的 useragent 来识别到底是浏览器访问,还是代码访问。
- 服务器识别浏览器访问的方法就是判断是否为Request headers 下的User-Agent,因此,我们只需要构造这个请求头的参数即可,以2.4为例,代码如下:
headers = {'User-Agent': 'Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, likeGecko) Chrome/70.0.3538.102 Safari/537.36'}
response = requests.post(url,data = Form_data,headers=headers)
- 除此之外,访问的频率过高,这个行为也不符合正常人类的行为,也会被封IP,这个问题有两个解决方案,第一就是增设延时,设3s抓取一次,代码如下:
import time
time.sleep(3)
- requests相应有proxies属性,为了提高效率,阔以从本质上解决问题,首先,构建自己的代理IP池,将其以字典的形式赋值给proxies,然后传输给requests,代码如下:
proxies = {
"http":"http://10.10.1.10:3128",
"https":"http://10.10.1.10:1080",
}
response = requests.get(url,proxies=proxies)