作業(yè)代碼:
#!/usr/bin/env python
# coding: utf-8
import sys
import time
import math
from bs4 import BeautifulSoup
import requests
number = 0
detail_list = []
def detail_info(detail_urls):
"""每個詳情頁的信息"""
global number, detail_list
for i in detail_urls:
number = number + 1
detail_data = requests.get(i)
time.sleep(1)
detail_soup = BeautifulSoup(detail_data.text, 'lxml')
# print detail_soup
title_list = detail_soup.select("div.pho_info > h4 > em")
# print title_list[0].get_text()
address = detail_soup.select("div.pho_info > p")
# print address[0]['title']
price = detail_soup.select("div.day_l > span")
# print price[0].get_text()
img = detail_soup.select("div.pho_show_r > div > ul.detail-thumb-nav > li > img")
# print img[0]['data-bigimg']
fangdong_img = detail_soup.select("div.js_box.clearfix > div.member_pic > a > img")
# print fangdong_img[0].get('src')
name = detail_soup.select("div.js_box.clearfix > div.w_240 > h6 > a")
# print name[0].get_text()
gender_str = detail_soup.select("div.js_box.clearfix > div.w_240 > h6 > span")
gender = gender_str[0]['class'][0]
if gender == 'member_girl_ico':
gender_unicode = u'女'
else:
gender_unicode = u'男'
detail_dict = {
'title':title_list[0].get_text(),
'address':address[0]['title'],
'price':price[0].get_text(),
'img_url':img[0]['data-bigimg'],
'fangdong_img_url':fangdong_img[0].get('src'),
'name':name[0].get_text(),
'gender':gender_unicode
}
# detail_list.append(detail_dict)
with open('result.txt','a') as f:
f.write(str(detail_dict)+"\n")
if number == 300:
sys.exit(1)
def get_per_page_urls(url):
"""獲取每一列表頁的詳情url列表"""
detail_urls = []
home_data = requests.get(url)
soup = BeautifulSoup(home_data.text, 'lxml')
detail_info_list = soup.select("#page_list > ul > li > a")
for i in detail_info_list:
detail_urls.append(i.get('href'))
return detail_urls
def get_per_detail_num():
"""獲取每一列表頁詳情url的數(shù)量"""
url = "http://bj.xiaozhu.com/search-duanzufang-p1-0/"
home_data = requests.get(url)
soup = BeautifulSoup(home_data.text, 'lxml')
count = len(soup.select("#page_list > ul > li"))
return count
def url(num=300):
"""根據(jù)需要爬取的信息數(shù)量,計算需要請求的列表頁url普气,返回列表頁url列表"""
# 需要爬取的頁數(shù)
# pages = num / get_per_detail_num() + 1
pages = int(math.ceil(float(num)/get_per_detail_num()))
list_urls = []
for page in range(pages):
url = "http://bj.xiaozhu.com/search-duanzufang-p{}-0/".format(page+1)
list_urls.append(url)
# print list_urls
return list_urls
for i in url():
# print i
detail_urls = get_per_page_urls(i)
# print detail_urls
detail_info(detail_urls)
print "%s 爬取完成" % i
總結(jié)
- BeautifulSoup 的使用
學(xué)習(xí)了一下 BeautifulSoup 的用法,并做了筆記
可以使用 CSS 選擇器佃延,通過 屬性现诀、類、id履肃、相對位置定位元素仔沿,使用.get("xx")``.find_all()``.get_text()
獲取元素中需要的信息
要確保 選擇器 是否可以唯一定位我們需要的元素,可以復(fù)制要篩選的內(nèi)容尺棋,在網(wǎng)頁源代碼中搜索封锉,看結(jié)果是否?是我們想要的
-
.text
方法
使用 beautifulsoup 解析網(wǎng)頁時,需要對 requests 請求的返回對象調(diào)用.text
方法: soup = Beautifulsoup(wb_data.text,'lxml')
膘螟,因為 requests 請求返回的是一個完整的 HTTP 響應(yīng)消息成福,包括響應(yīng)頭和響應(yīng)體,我們需要解析的是放在響應(yīng)體的中的 HTML 文檔荆残,所以用.text
提取 HTTP 響應(yīng)體
- 觀察瀏覽器發(fā)送的請求和得到的回復(fù)
chrome 瀏覽器中奴艾,右擊頁面,檢查内斯,選中彈出頁面最上方的network
標(biāo)簽蕴潦,刷新頁面像啼,可以看到瀏覽器加載頁面 HTML、JS潭苞、images 這些文件的過程忽冻,包括請求、回復(fù)此疹、內(nèi)容
- 模擬手機(jī)獲取頁面甚颂,獲取反爬取的信息
如果網(wǎng)頁既有PC端又有移動端,相對而言秀菱,移動端的js、html結(jié)構(gòu)會簡單清晰一些蹭睡,因為不同的手機(jī)瀏覽器可能不會完整加載 JS
可以在 chrome 的 檢查 中衍菱,點(diǎn)擊左上角的移動設(shè)備,選擇手機(jī)型號肩豁,刷新頁面脊串,模擬手機(jī)登陸。然后在network
頁簽左下選中一個請求清钥,在右側(cè)點(diǎn)擊headers
琼锋,找到請求頭部,復(fù)制 user-agent
祟昭,構(gòu)造一個字典缕坎,作為headers
添加到 requests 的頭部
wb_data = requests.get(url, headers=headers)
- 連續(xù)爬取多頁信息
可以查找 URL 規(guī)律,然后用 列表解析式 完成 URL 構(gòu)建
urls = [xx{}xx.format(str(i)) for i in range(num)]
- 反爬取
有些網(wǎng)站對爬蟲做了反爬取篡悟,比如限制請求頻率等谜叹,可以添加計時器,延長請求之間的間隔
import time # 導(dǎo)入 time 模塊
time.sleep(1) # 指定延遲時間搬葬,這里是 1s