近几日在实习过程中接触了python爬虫,在此记录一些心得与体会,也为自己做一些爬虫方面的备忘与笔记。
Requests官方文档:快速上手 — Requests 2.18.1 文档
Requests是一个对新手很是友好的库,我也将它作为我爬虫入门的首选工具。
首先导入Requests模块
import requests
我们在爬虫时为了避免被网站的防爬机制发现,我们可以通过F12可以在控制台查看浏览器访问时的header,并为我们的爬虫定制一个header
以客路网(https://www.klook.com/zh-CN/)为例:
我们往往需要User-Agent来伪装我们的爬虫
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
Requests有两种发送网络请求的方式:get与post。
一般通过F12可以在控制台查看所需爬取网页的网络请求方式
在Network下的Headers选卡很容易得知Request Method为get方式
res = requests.get(url = 'https://www.klook.com/zh-CN/', headers=headers)
print(res.text)
由此我们便可以得到网页的全部静态内容
那我们又该如何筛选出我们所需要的信息呢?
在此我选择了xpath的方式,xpath可以非常简单明确地抽取HTML中的信息
首先引入 LXML 库的 etree 模块
from lxml import etree
并利用上文得到的网页内容构造一个xpath解析的对象
html = etree.HTML(res)
接下来我们使用谷歌浏览器自带的路经查询功能,在所需爬取内容部分右击选择“检查”,便会自动定位到html中的相应位置,并继续右击选择“Copy”-“Copy Xpath”,我们便得到了此处的xpath.
我们以“热门目的地”中的“台北”为例:
根据xpath我们便可以定位“台北”的文本位置
name = html.xpath('/html/body/section[2]/div[1]/div[1]/div/div[1]/div[1]/div/a/div/div/span/b/text()')
print(name[0])
那么我们能否批量地获得其他地点的名字呢?
我们可以观察一下各个地点的xpath
台北:/html/body/section[2]/div[1]/div[1]/div/div[1]/div[1]/div/a/div/div/span/b
香港:/html/body/section[2]/div[1]/div[1]/div/div[1]/div[2]/div/a/div/div/span/b
澳门:/html/body/section[2]/div[1]/div[1]/div/div[1]/div[3]/div/a/div/div/span/b
我们很快就可以发现唯一的区别便是第五个div标签的值不同
我们可以通过一个简单的循环来获得所有的地名
for i in range(0, 8):
name_path ='/html/body/section[2]/div[1]/div[1]/div/div[1]/div[' + str(i) + ']/div/a/div/div/span/b/text()'
name = html.xpath(name_path)
现在我们尝试能否获取各地的图片信息
仍旧先研究台北,在定位图片在html中的位置后,我们向上寻找发现图片url在红框处,发现我们所需要的信息在"data-original"属性内,我们这时使用@来抽取标签属性
pic = html.xpath('/html/body/section[2]/div[1]/div[1]/div/div[1]/div[1]/div/@data-original')
print(pic[0])
完整代码如下
import requests
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
res = requests.get(url = 'https://www.klook.com/zh-CN/', headers=headers)
html = etree.HTML(res)
for i in range(0, 8):
name_path = '/html/body/section[2]/div[1]/div[1]/div/div[1]/div[' + str(i) + ']/div/a/div/div/span/b/text()'
pic_path = '/html/body/section[2]/div[1]/div[1]/div/div[1]/div[' + str(i) + ']/div/@data-original'
name = html.xpath(name_path)
pic = html.xpath(pic_path)
print(name[0])
print(pic[0])