现实世界网络连接
Client 一次http Request 请求,和服务端的一次 Response 相应。
爬虫原理
爬虫需要做如下事情:
1. 模拟对服务端的Request请求;
2. 接收Response 内容并解析、提取所需信息;
热身准备
俗话:工欲善其事必先利其器,以下是开始网页抓取、爬虫的利器。
网页基本构造的”精准外科手术刀”;
利用网页定位利器--Chrome浏览器。
我们都知道HTML Dom树表示,可以很清晰从上图看到整个树结构。
爬虫库介绍(Python3以上);
Requests、BeautifulSoup4、Lxml库是Python爬虫主要的第三方库。Requests库:请求网站获取网页数据。[官方文档][1]
BeautifulSoup4: 可以从HTML或XML文件中提取数据为Soup文档。 [官方文档][2]
- Lxml: 使用Xpath 语法解析定位网页数据,解析速度快。[官方文档][3]
简单实践
对酷狗音乐TOP500,抓取榜单歌曲
from bs4 import BeautifulSoup
import requests
url = "http://www.kugou.com/yy/rank/home/1-8888.html?from=rank"
headers = {
"User-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36"
}
html = requests.get(url, headers=headers)
soup = BeautifulSoup(html.text, 'lxml')
tag_list = soup.select('#rankWrap > div.pc_temp_songlist > ul > li:nth-of-type(1) > a')
print(tag_list)
运行结果如下:
这里再对淘宝网进行分析:
会发现淘宝网的数据不是在页面中,而是处于javaScript中,这就需要我们要用到正则表达式对数据进行过滤:
import requests
from bs4 import BeautifulSoup
import re
import json
import pymysql
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36'
}
url = 'https://s.taobao.com/search?q=%E8%B7%B3%E7%BB%B3&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306&sort=sale-desc&bcoffset=0&p4ppushleft=%2C44&s={}'
urls = [url.format(num*44) for num in range(0, 10)]
conn = pymysql.connect(host='', user='', password='', db='', port=3306,
charset='utf8')
cursor = conn.cursor()
print(urls)
for single_url in urls:
page = requests.get(single_url, headers=headers)
soup = BeautifulSoup(page.text, 'html.parser')
content = re.findall('g_page_config = {(.*?)};', soup.text)[0]
sale = '{' + content + '}'
result = json.loads(sale)
goods = result['mods']['itemlist']['data']['auctions']
for good in goods:
sql = 'insert into crawl_data(data) values(%s)'
good_str = json.dumps(good)
cursor.execute(sql, good_str)
cursor.connection.commit()
运行结果可以看到: