前面已经进行了爬虫基础部分的学习,于是自己也尝试爬了一些网站数据,用的策略都是比较简单,可能有些因素没有考虑到,但是也爬取到了一定的数据,下面介绍两个爬过的案例。
链家网站的爬取不难,我爬取的主要是租房数据,看一下页面:
我需要爬取的字段有房子的名称,小区,面积,朝向,户型,以及房租。
代码比较简单,主要使用了requests和xpath进行爬取,爬取了100页得数据。
import requests
import pandas as pd
import re
from lxml import etree
url = 'https://bj.lianjia.com/zufang/pg'
resp = requests.get(url)
time.sleep(0.5)
resp_text = resp.text
tree = etree.HTML(resp.text)
info_list = tree.xpath('//div[@class="content__list"]/div')
for info in info_list:
name = info.xpath('./a/@title')
#detail_1 = info.xpath('.//div[@class="content__list--item--main"]/p[2]//text()')
location = info.xpath('.//div[@class="content__list--item--main"]/p[2]/a/text()')
detail_list = info.xpath('.//div[@class="content__list--item--main"]/p[2]/text()')
detail_string = ''.join(detail_list)
detail_text = re.sub('[\r\n\t\s//\-]', '', detail_string)
price = tree.xpath('//*[@id="content"]/div[1]/div[1]/div[1]/div/span//text()')
price = ''.join(price)
#detail_1 = info.xpath('.//div[@class="content__list--item--main"]/p/a/text()')
#detail_2 = info.xpath('.//div[@class="content__list--item--main"]/p/i/text()')
print(name,location,detail_text,price)
f.write("{},{},{},{}\n".format(name,location,detail_text,price))
上面给的代码是爬取一个页面的,如果要爬取多个页面写个循环就好了。爬取保存后得数据如下图:
保存格式可以自行调整成自己想要的格式。
难点分析:基本上没有什么难点,主要是一些字符串的处理。第二个就是后面我由于爬取网站次数过多被检测到了,爬取的时候可以设置一下time sleep()
未解决的问题:我只能爬取到100页数据,共3000个房源左右,但是页面却显示共有5万多套租房,我还不知道怎么爬取到其他的数据。
最近在找实习嘛,所以页爬取了一下实习僧网站。实习僧网站有个问题就是字体反爬。
字体反爬,就是一些关键数据你在网页上观看时他是正常的,但是在使用浏览器的网页检查时却显示的是一个个的方块,这样我们就没有办法从网页中将数据正确的爬取下来。看下实习僧网站的例子:
实习僧网站就是使用了自己的一套规则。那怎么获取到这个对应的编码规则,我采取的方式就是把目标数据先经过utf-8编码后,输出对应的十六进制字符,每个字符(包括数字和汉字)都应对\分割的三个字符组成的三块内容,分割如下:
这种对应的编码会更新,获取编码用下面的代码形式就可以,以获取工资数据为例:
这个公司是200-400/天的,获取到的编码就如上图所示,这个代码是我之后跑的,可以看到编码已经更新了。
爬取实习僧网站使用的requests和bs4,先给下完整的代码:
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
def decode_font(data):
data = data.replace(b'\xee\xa8\x92', b'0')
data = data.replace(b'\xee\xa2\x9f', b'1')
data = data.replace(b'\xee\x9f\xab', b'2')
data = data.replace(b'\xef\x99\x95', b'3')
data = data.replace(b'\xef\x80\x90', b'4')
data = data.replace(b'\xef\x8f\xb4', b'5')
data = data.replace(b'\xef\x89\x90', b'6')
data = data.replace(b'\xee\x92\x99', b'7')
data = data.replace(b'\xef\xa3\x9c', b'8')
data = data.replace(b'\xee\x9b\xa5', b'9')
data = data.decode('utf-8')
return data
headers={
'Connection':'close',
"User-Agent": 'Mozilla/5.0'
}
sess = requests.Session()
detail_urls=[]
for j in range(1,23):
url=f'https://www.shixiseng.com/interns?keyword=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E4%B9%A0&page={j}&city=%E5%85%A8%E5%9B%BD'
page_text = sess.get(url=url,headers=headers).text
soup = BeautifulSoup(page_text,'lxml')
for i in range(len(soup.findAll('div',class_='intern-wrap intern-item'))):
detail_url = soup.select('.f-l.intern-detail__job a')[i]['href']
title = soup.select('.f-r.intern-detail__company>p>a')[i]['title']
#获取到各个详情链接
# print(title,detail_url)
detail_urls.append(detail_url)
print(len(detail_urls))
上面的代码中先是定义了一个解码函数,然后先获取到各个详情链接,下面再获取详情链接中我需要的各个字段。我需要的字段有公司名称,招聘岗位名称,工资,所在地区,学历,工作天数,实习时长以及截止日期。
job_names=[]
comps=[]
salaries=[]
locates=[]
degrees=[]
weekdays=[]
lasts=[]
deadlines=[]
for url in detail_urls:
page_text = sess.get(url=url,headers=headers).text
soup = BeautifulSoup(page_text,'lxml')
#1.找到div class=new_job_name,提取岗位名称
job_name = soup.select('.new_job_name')[0]['title']
#2.找到公司名称
comp = soup.select('div.com_intro > a.com-name')[0].text.strip()
#3.找到工资
salary = decode_font(soup.select('.job_msg>span')[0].text.encode('utf-8'))
#4.找到地区
locate = soup.select('.job_msg>span')[1]['title']
#5.找到学位要求
degree = soup.select('.job_msg>span')[2].text
#6.每星期上班天数
weekday = decode_font(soup.select('.job_msg>span')[3].text.encode('utf-8'))
#7.实习时长
last = decode_font(soup.select('.job_msg>span')[4].text.encode('utf-8'))
#8.截止日期
deadline = decode_font(soup.select('.cutom_font')[-1].text.encode('utf-8'))
job_names.append(job_name)
comps.append(comp)
salaries.append(salary)
locates.append(locate)
degrees.append(degree)
weekdays.append(weekday)
lasts.append(last)
deadlines.append(deadline)
dataframe = pd.DataFrame({'岗位名称':job_names,
'公司名称':comps,
'工资':salaries,
'工作地点':locates,
'学位要求':degrees,
'工作日':weekdays,
'实习时长':lasts,
'截止日期':deadlines,
'岗位链接':url})
dataframe.to_csv(r"./shixiseng_all.csv",sep=',')
获取到这些字段数据后,把它们存入到csv文件中,如下图。
因为我想找数据分析实习岗位相关,所以我爬取的是这方面的实习,实习僧网站上面数据分析实习岗位数据我爬的时候只有290条。对其他职位感兴趣的改一下初始的url就好了。
难点分析:字体反爬,编码规则,访问的时候需要携带cookie。
未解决的问题:对于编码持续更新这一块还没有较好的解决办法。
本来还想爬拉勾的,但是因为我爬取的次数太多了,技术也有些不到家,拉勾不让我爬了,用了ip代理也没有用,然后header里面也放了很多东西也没有用,不知道现在解封了没有,还是技术不到家。
还爬取了一个51job的,51job网站是用scrapy和xpath进行爬取的,但是还有些小问题,之后再整理好了。
这段时间真的是因为找实习愁到头大,前两天实在烦闷,家里人提议去庐山玩,便想着出去散散心透透气回好点就去了。庐山还是值得一玩的,就是回来之后我的腿已经废了…