爬取思路
目標網站妹子圖url:http://www.meizitu.com/a/more_1.html
通過觀察我們發現,索引頁包含圖片所在網頁的連接,我們可以通過索引頁的連接地址訪問詳情頁,進而找到圖片。所以思路就是1. 索引頁—2. 分析索引頁得到詳情頁的地址— 3. 訪問詳情頁—- 4. 分析詳情頁得到圖片的地址,— 5. 進而下載到本地
爬取結果:
實戰部分
需要用到的技術
requests庫的基本用法
BeautifulSoup庫的基本用法
import os
import requests
from requests import RequestException
from bs4 import BeautifulSoup
from hashlib import md5
from multiprocessing import Pool
訪問索引頁
使用requests庫訪問索引頁,查看網頁源代碼發現網頁編碼爲 ‘gb2312’ ,需要修改返回編碼
# 訪問索引頁
def get_page_index(url):
try:
response = requests.get(url)
if response.status_code == 200:
# 轉換編碼
response.encoding = 'gb2312'
#print(response.text)
return response.text
return None
except RequestException:
print('訪問索引頁出錯',url)
得到詳情頁(圖片所在頁面)的地址
瀏覽器中審查元素,發現詳情頁的地址在一個類名爲’ . pic ’ 下的 a 標籤中 ’ href ‘中,使用BeautifulSoup解析網頁,選擇解析器爲 ’ lxml ’ 之後使用生成器返回地址
# 處理索引頁
def parse_page_index(html):
soup = BeautifulSoup(html, 'lxml')
page_urls = soup.select(".pic > a")
for item in page_urls:
# print(item)
yield item.attrs['href']
- 訪問詳情頁
#訪問詳情頁
def get_page_detail(url):
print('正在訪問',url)
try:
response = requests.get(url)
if response.status_code == 200:
response.encoding = 'gb2312'
return response.text
return None
except RequestException:
print('訪問詳情頁出錯',url)
return None
分析詳情頁得到圖片的地址
分析詳情頁,圖片在 id 爲 ’ picture ‘下 p 標籤下的 img 標籤中,調用下載圖片的函數,將圖片地址下的圖片下載下來。
# 解析詳情頁
def parse_page_detail(html):
print('正在解析')
soup = BeautifulSoup(html,'lxml')
page_urls = soup.select('#picture > p > img')
for page_url in page_urls:
download_pic(page_url.attrs['src'])
下載圖片到本地
得到圖片所在的地址後,我們可以發現,圖片並不是保存在該網站上的而是託管在其他的網站,該網站需要設置請求頭,否則會拒絕爬蟲訪問。之後設置圖片保存的路徑,使用MD5將圖片的名字統一長度,避免重名。
#訪問圖片地址並下載
def download_pic(url):
print('訪問圖片地址',url)
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
try:
response = requests.get(url,headers = header)
if response.status_code == 200:
content = response.content
file_path = '{0}/{1}.{2}'.format(os.getcwd()+'/picture2',md5(content).hexdigest(),'jpg')
if not os.path.exists(file_path):
with open(file_path,'wb') as f:
f.write(content)
f.close()
#print('ok')
except RequestException:
print('訪問圖片或存儲出錯')
main函數
def main(index):
html = get_page_index('http://www.meizitu.com/a/more_'+ str(index) +'.html')
# parse_page_index使用yield生成器返回信息
for detail_page_url in parse_page_index(html):
detail_html = get_page_detail(detail_page_url)
parse_page_detail(detail_html)
print('爬取完成')
if __name__ == '__main__':
# 多線程爬取第一頁和第二頁
pool = Pool()
groups = [i for i in range(1,3)]
pool.map(main,groups)
源碼地址:
https://github.com/Link-Secret/Python-crawler/blob/master/spider/meizitu.py