作业代码:
#!/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的数量"""
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):
"""根据需要爬取的信息数量,计算需要请求的列表页url,返回列表页url列表"""
# 需要爬取的页数
# 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
总结
- BeautifulSoup 的使用
学习了一下 BeautifulSoup 的用法,并做了笔记
可以使用 CSS 选择器,通过 属性、类、id、相对位置定位元素,使用.get("xx")``.find_all()``.get_text()
获取元素中需要的信息
要确保 选择器 是否可以唯一定位我们需要的元素,可以复制要筛选的内容,在网页源代码中搜索,看结果是否�是我们想要的
-
.text
方法
使用 beautifulsoup 解析网页时,需要对 requests 请求的返回对象调用.text
方法: soup = Beautifulsoup(wb_data.text,'lxml')
,因为 requests 请求返回的是一个完整的 HTTP 响应消息,包括响应头和响应体,我们需要解析的是放在响应体的中的 HTML 文档,所以用.text
提取 HTTP 响应体
- 观察浏览器发送的请求和得到的回复
chrome 浏览器中,右击页面,检查,选中弹出页面最上方的network
标签,刷新页面,可以看到浏览器加载页面 HTML、JS、images 这些文件的过程,包括请求、回复、内容
- 模拟手机获取页面,获取反爬取的信息
如果网页既有PC端又有移动端,相对而言,移动端的js、html结构会简单清晰一些,因为不同的手机浏览器可能不会完整加载 JS
可以在 chrome 的 检查 中,点击左上角的移动设备,选择手机型号,刷新页面,模拟手机登陆。然后在network
页签左下选中一个请求,在右侧点击headers
,找到请求头部,复制 user-agent
,构造一个字典,作为headers
添加到 requests 的头部
wb_data = requests.get(url, headers=headers)
- 连续爬取多页信息
可以查找 URL 规律,然后用 列表解析式 完成 URL 构建
urls = [xx{}xx.format(str(i)) for i in range(num)]
- 反爬取
有些网站对爬虫做了反爬取,比如限制请求频率等,可以添加计时器,延长请求之间的间隔
import time # 导入 time 模块
time.sleep(1) # 指定延迟时间,这里是 1s
网友评论