经朋友介绍,认识到了python实战:四周实习爬虫系统,然后看了一下试看教程,觉得课程挺不错的,→_→重点是对于学生党有点贵啊,经过几天纠结还是决定加入这个课程了。
现在就不多说废话了,直接写心得,首先按照课程要求安装lxml,Beautiful Soup ,Requests,对了,忘记说我的环境,WIN7 64位,python3.4版本,其实有心换MAC,奈何非我们这种普通人买的起的,所以就WIN环境先用着,因为我提前装了PIP,安装这些都挺容易的,直接pip3 install xxxx就行了,反正我中间没有遇到错误。
什么环境也准备好了,然后开基础课程,什么认识网页结构之类的就不多说了,反正我也只是了解一下这个,说具体的也不是太懂。然后主要是定位网页元素了,我们重点是要学习这个,用google chrome浏览器中的检查,就可以查询到结构。当然刚开始都是比较简单的,我觉得是比较好学的。
剩下的就是import各种库,然后使用代码了:
刚开始用BeautifulSoup还是认真的打一下代码吧,soup = BeautifulSoup(html,'lxml')
这是soup html都是变量 lxml是解析网页用的五个库中的一个
课程中所讲的节点什么的似乎没什么难的,兄弟节点和父子节点应该都是可以看得懂的,只要学过高中生物遗传部分的应该都不难看懂。
剩下的就是自己实际操作了,课程自带的网页就是很好的练手工具了,初步练手之后就是实战58同城了。
先爬一个界面下的详细信息,源代码如下
url = 'http://bj.58.com/pingbandiannao/25853969546167x.shtml'
wb_data = requests.get(url)
soup = BeautifulSoup(wb_data.text,'lxml')
url这个不用说了,是你要访问的地址,然后用requests获取内容储存到变量wb_data中,然后使用BeauifulSoup解析到soup变量中,然后我们来提取一下想要的内容,
title = soup.title.text
price = soup.select('#content span.price')
data = soup.select('.time')
area = soup.select('.c_25d')
这里就是提取想要的内容,因为标题是直接显示在网页头的,所以使用了取巧方法titile.text,价格、更新时间、还有区域是使用的查看结构的方式去获取的,最后把他们封装在字典中,
data = {
'标题':title,
'价格':price[0].text,
'时间':data[0].text,
'所属区域':list(area[0].stripped_strings) if soup.find_all('span','c_25d') else None,
'类型':'个人'if who_selit==0 else'商家',
'浏览次数':get_view_from(url)
}
因为区域部分有些网页中是没有的,所以使用了if作为条件判断,如果没有就返回控制None,幼儿画就打印,至于类型部分有个if判断是后期判断抓取的数据是个人还是商家的列表所使用,这里没什么关系。这段代码写完以后就是print打印一下内容了。
抓取单网页的内容就结束了,下面说一下返回到列表页面去抓当前列表的所有内容。
urls=[]
list_view = 'http://bj.58.com/pbdn/{}/pn2/'.format(str(who_selit))
wb_data = requests.get(list_view)
soup = BeautifulSoup(wb_data.text,'lxml')
for link in soup.select('td.t > a.t'):
if str('jump') in str(link) or str('zhuanzhuan')in str(link):
pass
else:
urls.append(link.get('href').split('?')[0])
return urls
先说下代码的步骤,定义下urls变量为一个列表,然后定义一下list_view的内容,这里就是58额列表页面,最后的方法.format(str(who_selit)),是替换一下内容,这个是比较简单,who_selit变量就是要替换进去的内容,然后就是解析网页什么的,通过select查找网页结构获取想要的网址,写个循环进去获取每个商品的网址,因为58里面有个转转界面,所以写个if判断下获取的网址,如果是转转的就pass了,不是的话加入到urls这个变量中。
由于浏览次数这个是JS控制的,并且和商品的URL是有一定关系的,这里我贴一下代码,这段代码我只能看懂,如果让我说个123还真说不出来。
id = url.split('/')[-1].strip('x.shtml')
api = 'http://jst1.58.com/counter?infoid={}'.format(id)
js = requests.get(api)
views = js.text.split('=')[-1]
到这里似乎就差不多了 封装一下各个部分,然后做个完整的程序出来,下面贴一下完整的代码
#-*-coding:utf-8-*-
from bs4 import BeautifulSoup
import requests
import time
def get_urls(who_selit=0):
urls=[]
list_view = 'http://bj.58.com/pbdn/{}/pn2/'.format(str(who_selit))
wb_data = requests.get(list_view)
soup = BeautifulSoup(wb_data.text,'lxml')
for link in soup.select('td.t > a.t'):
#剔除转转界面
if str('jump') in str(link) or str('zhuanzhuan')in str(link):
pass
else:
urls.append(link.get('href').split('?')[0])
return urls
#返回所有的商品界面
def get_view_from(url):
id = url.split('/')[-1].strip('x.shtml')
api = 'http://jst1.58.com/counter?infoid={}'.format(id)
js = requests.get(api)
#获取一下浏览次数
views = js.text.split('=')[-1]
return views
def get_info(who_selit=0):
urls = get_urls(who_selit)
for url in urls:
wb_date = requests.get(url)
soup = BeautifulSoup(wb_date.text,'lxml')
title = soup.title.text
price = soup.select('#content span.price')
data = soup.select('.time')
area = soup.select('.c_25d')
data = {
'标题':title,
'价格':price[0].text,
'时间':data[0].text,
'所属区域':list(area[0].stripped_strings) if soup.find_all('span','c_25d') else None,
'类型':'个人'if who_selit==0 else'商家',
'浏览次数':get_view_from(url)
}
time.sleep(0.5)
#延迟一下 避免58的反爬虫
print(data)
#解析每个商品界面并且整理到字典中并且输出
get_info()
以上代码经过2016.05.06测试可以使用并且正确输出