学Python也有段时间了,目前学到了Python的类。个人感觉Python的类不应称之为类,而应称之为数据类型,只是数据类型而已!只是数据类型而已!只是数据类型而已!重要的事情说三篇。

据书上说一个.py(常量、全局变量、函数、数据类型)文件为一个模块,那么就有了一种感觉:常量、全局变量、函数、数据类型是同一“级别的”。在此不多说了,收回自己的心思来看爬虫吧!

1、进百合网官网,单击“搜索”、单击“基本搜索”,这时会跳向另一个页面,该页面为登录页面(如图):

2、找到login.js,具体步骤:F12、F5、network、js(如图):

3、找登录时的异步请求,该请求在login.js中(如图):

 4、单击“基本搜索”,会得到两个异步请求

1:获取160个id  (如图):

2:根据id得到用户详细信息,为json数据(如图):

说了这么多,该上代码了(总共261行):

baihe.py:

 #__author: "YuWei"
#__date: 2018/2/4
import requests
import time
import pymssql
import os # 8个人为一组,该常量用于判断列表的长度是否与网站一致
FING_INDEX = 8
# 请求头,伪装成浏览器
HEADERS = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'}
# 代理ip,防止被百合网封ip
HTTP_IP_PROXIES_1 = 'http://211.151.58.5:80'
HTTP_IP_PROXIES_2 = 'http://192.168.200.1:8081' def baihe_db(personal):
"""
数据库相关的操作 :param personal: 为字典类型,封装着个人具体信息
:return: 无
"""
# 数据连接
conn = pymssql.connect(host='localhost', user='YUANWEI', password='123456c', database='Baihe',charset='utf8')
cur = conn.cursor() # 游标
sql = """insert into users values({},'{}',{},'{}','{}','{}',{},'{}','{}','{}','{}');""" \
.format(personal['userID'], personal['nickname'], personal['age'], '男' if personal['gender'] == "" else '女',
personal['cityChn'], personal['educationChn'], personal['height'],
'没房' if personal['housing'] == 0 else '有房', '没车' if personal['car'] == 0 else '有车',
personal['incomeChn'],personal['marriageChn'])
print('sql: ', sql)
try:
cur.execute(sql) # 执行sql语句
save_photo(personal, get_miss_photo_binary(personal['headPhotoUrl'])) # 保存头像
print('成功获取该用户',personal['userID'])
except pymssql.IntegrityError:
print('该用户已存在 ',personal['userID'])
except SystemError as sy: # 向err.txt导入错误日志
with open('err.txt','a',encoding='utf8') as file:
file.write(personal['nickname'] + ' ' + str(personal['userID']) + ' 错误信息:' + str(sy) + '\n') # 写
except pymssql.ProgrammingError as pp:
with open('err.txt','a',encoding='utf8') as file:
file.write(personal['nickname'] + ' ' + str(personal['userID']) + ' 错误信息:' + str(pp) + '\n')
conn.commit() # 提交
time.sleep(1)
cur.close()
conn.close() def personal_data(lists):
"""
获取一组的详细信息,最多为8个 :param lists: 列表类型,封装着一组信息
:return: 无
"""
for personal_data_dict in lists: # 遍历一组信息
baihe_db(personal_data_dict) def get_miss_photo_binary(photo_url):
"""
获取照片的二进制数据 :param photo_url: 个人头像的url
:return: 二进制数据
"""
binary = ''
try:
# 向服务器发送get请求,下载图片的二进制数据
binary = requests.get(photo_url, headers=HEADERS,proxies={"http": HTTP_IP_PROXIES_2}).content
except requests.exceptions.MissingSchema as rem:
print(rem)
except requests.exceptions.ProxyError: # 代理网络连接慢或无网络
time.sleep(5)
# 递归调用get_miss_photo_binary()
get_miss_photo_binary(photo_url)
return binary def save_photo(personal,binary):
"""
以'E:/Baihe/1/'为文件目录路径 或 以'E:/Baihe/0/'为文件目录路径
以 name + id + .jpg 或 以 id + .jpg 为文件名
有可能无相片 :param personal: 字典类型,封装着个人具体信息
:param binary: 二进制数据
:return: 无
"""
if binary != '':
file_path = 'E:/Baihe/1/' if personal['gender'] == "" else 'E:/Baihe/0/' #
if not os.path.exists(file_path): # 如果该路径不存在
os.makedirs(file_path) # 创建该路径
try:
# 向file_path路径保存图片
with open(file_path + personal['nickname'] + str(personal['userID']) + '.jpg','wb') as file:
file.write(binary)
except OSError:
with open(file_path + str(personal['userID']) + '.jpg','wb') as file:
file.write(binary) def no_exact_division(miss_id_list):
"""
当包含用户id的列表长度不能被8整除且列表长度小于8时调用该方法 :param miss_id_list: 为列表类型,封装着用户id
:return: 无
"""
miss_info_lists = ba.get_miss_info(miss_id_list) # 获取列表的个人信息
personal_data(miss_info_lists) # 遍历一组的信息 class Baihe(object): def __init__(self,account,password):
"""
初始化
:param account: 账号
:param password: 密码
"""
self.is_begin = True # 开始爬取数据
self.index = 0 # 控制self.info长度为8个
self.info = [] # 临时保存用户id
self.page = 61 # 页码
self.account = account # 账号
self.password = password # 密码
self.req = requests.session() # 会话,保证Cookie一致 def login(self):
"""
登录 :return: 无
"""
# 登录的url
url_login = 'http://my.baihe.com/Getinterlogin/gotoLogin?event=3&spmp=4.20.87.225.1049&' \
'txtLoginEMail={}&txtLoginPwd={}'.format(self.account,self.password)
login_dict = {}
try:
# 向服务器发送get请求
login_dict = self.req.get(url_login,headers=HEADERS,proxies={"http": HTTP_IP_PROXIES_1},timeout=500).json()
except requests.exceptions.ProxyError: # 代理网络连接慢或无网络
time.sleep(5)
# 递归调用self.login()
self.login()
time.sleep(3)
print('login: ',login_dict)
self.req.keep_alive = False # 关闭会话多余的连接
if login_dict['data'] == 1:
print('登录成功')
else:
print('登录失败, 30分钟以后自动登录。。。。。。。。')
time.sleep(1800)
# 递归调用self.login()
self.login()
print('login is cookie ', requests.utils.dict_from_cookiejar(self.req.cookies)) # 查看登录后的会话cookie def filtrate_miss(self,pages):
"""
根据条件筛选数据,不提供条件参数 :param pages: 页码。该网站只提供62页的数据
:return: 包含160个用户的id的列表
"""
time.sleep(2)
# 获取用户id的url
url_miss = 'http://search.baihe.com/Search/getUserID'
# from表单数据
params_miss = {"minAge": 18, "maxAge": 85, "minHeight": 144, "maxHeight": 210, "education": '1-8',
"income": '1-12', "city": -1, "hasPhoto": 1, "page": pages, "sorterField": 1}
miss_dict = {}
try:
# 发送post请求
miss_dict = self.req.post(url_miss,data=params_miss,headers=HEADERS,proxies={'http':HTTP_IP_PROXIES_2}).json()
except requests.exceptions.ProxyError: # 代理网络连接慢或无网络
time.sleep(5)
# 递归调用self.filtrate_miss()
self.filtrate_miss(pages)
time.sleep(2)
print('miss is cookies ', requests.utils.dict_from_cookiejar(self.req.cookies)) # 查看筛选后的会话cookie
print('miss dict: ',miss_dict)
print(len(miss_dict['data']),'个')
return miss_dict['data'] def get_miss_info(self,infos):
"""
获取用户详细信息 :param infos: 列表类型,封装着个人id,可能为一组(8),或小于8个
:return: 包含一组的详细信息
"""
if len(infos) == FING_INDEX: # infos列表长度等于8时
url_info = 'http://search.baihe.com/search/getUserList?userIDs={},{},{},{},{},{},{},{}'\
.format(infos[0],infos[1],infos[2],infos[3],infos[4],infos[5],infos[6],infos[7])
else: # infos列表长度小于8时
bracket = '' # 参数userIDs的值
for lens in range(len(infos)):
bracket += (str(infos[lens]) + ',') # 构造该表示:"{},{},{},{},{},{},{},{},"
# 获取用户详细信息的url bracket[:len(bracket)-1]: 分片,干掉最后一个“,”
url_info = 'http://search.baihe.com/search/getUserList?userIDs=' + bracket[:len(bracket)-1]
miss_info = {}
try:
# 发送post请求
miss_info = self.req.post(url_info,headers=HEADERS,proxies={'http':HTTP_IP_PROXIES_2}).json()
except requests.exceptions.ProxyError: # 代理网络连接慢或无网络
time.sleep(5)
# 递归调用self.get_miss_info()
self.get_miss_info(infos)
time.sleep(2)
try:
return miss_info['data']
except KeyError:
time.sleep(2)
self.get_miss_info(infos) def exact_division(self,miss_id_list):
"""
当包含用户id的列表长度能被8整除或包含用户id的列表长度不能被8整除且包含用户id的列表长度大于8 :param miss_id_list: id信息列表(160)
:return: 无
"""
for user_id in miss_id_list:
self.index += 1
self.info.append(user_id)
if ba.index == FING_INDEX:
print('user id: ', self.info)
miss_info_list = ba.get_miss_info(self.info) #
if None != miss_info_list:
# 使self.index,self.info为初值,以便8人一组
self.index = 0
self.info = []
print('miss info list: ', miss_info_list)
personal_data(miss_info_list) # 遍历一组(8)的信息
else:
print('miss info list is null')
continue def main(self):
"""
具体实施 :return: 无
"""
self.login() # 登录
while self.is_begin: # 开始
print('正在获取',self.page,'页.......')
miss_id_list = self.filtrate_miss(self.page) # 获取用户id列表
if len(miss_id_list) != 0: # 列表有id
num = len(miss_id_list) % FING_INDEX # 模运算
if num == 0: # 被8整除
self.exact_division(miss_id_list)
else: # 没有被8整除 , 虽然该分支没有执行,但还是要加上。因为该网站总是提供160个id
print('余数: ',num)
if len(miss_id_list) > FING_INDEX: # id列表的长度大于8
copy_miss_id_list = miss_id_list[:len(miss_id_list) - num] # 分片 取8个一组
self.exact_division(copy_miss_id_list)
no_exact_division(miss_id_list[len(miss_id_list) - num:]) # 余下的个人信息
else:
no_exact_division(miss_id_list) # 小于8个人的个人的信息
else:
print('数据已爬完。。。。。')
self.is_begin = False
self.page += 1
time.sleep(10)
# 运行
if __name__ == '__main__':
ba = Baihe('xxxxxxx', 'xxxxxxxxxx')
ba.main()

温馨提示:想爬女的,就找个性别为男的账号。想爬男的,就找个性别为女的账号。

 如果要简单的分析一下所爬的数据,建议用男的账号,女的账号反复爬那么3-5次,这样数据才有有效性。

python3 爬取百合网的女人们和男人们的更多相关文章

  1. Python爬虫 爬取百合网的女人们和男人们

    学Python也有段时间了,目前学到了Python的类.个人感觉Python的类不应称之为类,而应称之为数据类型,只是数据类型而已!只是数据类型而已!只是数据类型而已!重要的事情说三篇. 据书上说一个 ...

  2. 基于爬取百合网的数据,用matplotlib生成图表

    爬取百合网的数据链接:http://www.cnblogs.com/YuWeiXiF/p/8439552.html 总共爬了22779条数据.第一次接触matplotlib库,以下代码参考了matpl ...

  3. Python3爬取豆瓣网电影信息

      # -*- coding:utf-8 -*- """ 一个简单的Python爬虫, 用于抓取豆瓣电影Top前250的电影的名称 Language: Python3.6 ...

  4. Python3爬取人人网(校内网)个人照片及朋友照片,并一键下载到本地~~~附源代码

    题记: 11月14日早晨8点,人人网发布公告,宣布人人公司将人人网社交平台业务相关资产以2000万美元的现金加4000万美元的股票对价出售予北京多牛传媒,自此,人人公司将专注于境内的二手车业务和在美国 ...

  5. python3爬取网页

    爬虫 python3爬取网页资源方式(1.最简单: import'http://www.baidu.com/'print2.通过request import'http://www.baidu.com' ...

  6. 网络爬虫之定向爬虫:爬取当当网2015年图书销售排行榜信息(Crawler)

    做了个爬虫,爬取当当网--2015年图书销售排行榜 TOP500 爬取的基本思想是:通过浏览网页,列出你所想要获取的信息,然后通过浏览网页的源码和检查(这里用的是chrome)来获相关信息的节点,最后 ...

  7. 使用python爬取东方财富网机构调研数据

    最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了 ...

  8. Node.js爬虫-爬取慕课网课程信息

    第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...

  9. python 爬虫之爬取大街网(思路)

    由于需要,本人需要对大街网招聘信息进行分析,故写了个爬虫进行爬取.这里我将记录一下,本人爬取大街网的思路. 附:爬取得数据仅供自己分析所用,并未用作其它用途. 附:本篇适合有一定 爬虫基础 crawl ...

随机推荐

  1. HDU 1000 A + B Problem(指针版)

    A + B Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  2. 数学3(博弈+splya)

    数学3(博弈+splya) 标签: 数学 hdu_5194 (打表找规律) 题意 有n和黑球和m个白球,现在一个个的取出这些球,如果是黑球则当前标记为1,白球为0,那么当取完这些球会得到一些序列.问你 ...

  3. TI-RTOS 之 GPIO中断(按键)

    TI-RTOS 之 GPIO中断(按键) 前面已经用过LED, 定时器,这次来了解GPIO的中断是怎么用的,从CC1310+TI-RTOS的例程可以直接找到相应的例子程序,它的关键是在于要使能中断,也 ...

  4. linux安装navicat全程记录

    国庆期间自己在试着用linux(ubuntu),献上navicat安装方法,以及很多教程里没有写的一些小东西 step1: 去navicat官网下载安装包,网址:http://www.navicat. ...

  5. Maven中央仓库源地址改为阿里云(IDEA)

    我的Maven是IDEA2017.1.2集成的,所以settings.xml在此位置 E:\Program Files\JetBrains\IntelliJ IDEA 2017.1.2\plugins ...

  6. SpringMVC,SpringBoot文件下载

    前言 最近严查security, 导致原来暴露出去的s3不能用了,不允许public的s3,暂时的折中方案是自己做跳转.于是需要在SpringMVC中实现文件下载功能. 关于文件存储的设计 文件存储通 ...

  7. Java进阶篇(三)——Java集合类

    集合可以看作一个容器,集合中的对象可以很容易存放到集合中,也很容易将其从集合中取出来,还可以按一定的顺序摆放.Java中提供了不同的集合类,这些类具有不同的存储对象的方式,并提供了相应的方法方便用户对 ...

  8. NSDate的常用用法

    1. 创建或初始化可用以下方法 用于创建NSDate实例的类方法有 + (id)date; 返回当前时间 + (id)dateWithTimeIntervalSinceNow:(NSTimeInter ...

  9. Abp.NHibernate连接PostgreSQl数据库

    Abp.NHibernate动态库连接PostgreSQl数据库 初次接触Abp框架,其框架中封装的操作各类数据的方法还是很好用的,本人还在进一步的学习当中,并将利用abp.NHibernate类库操 ...

  10. mysql 查询今天,昨天,上个月sql语句 注解

    今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天Select * FROM 表名 Where TO_DAYS( NOW( ) ...