python3 爬取百合网的女人们和男人们

学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:

  1 #__author: "YuWei"
  2 #__date: 2018/2/4
  3 import requests
  4 import time
  5 import pymssql
  6 import os
  7
  8 # 8个人为一组,该常量用于判断列表的长度是否与网站一致
  9 FING_INDEX = 8
 10 # 请求头,伪装成浏览器
 11 HEADERS = {‘User-Agent‘:‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0‘}
 12 # 代理ip,防止被百合网封ip
 13 HTTP_IP_PROXIES_1 = ‘http://211.151.58.5:80‘
 14 HTTP_IP_PROXIES_2 = ‘http://192.168.200.1:8081‘
 15
 16 def baihe_db(personal):
 17     """
 18     数据库相关的操作
 19
 20     :param personal: 为字典类型,封装着个人具体信息
 21     :return: 无
 22     """
 23     # 数据连接
 24     conn = pymssql.connect(host=‘localhost‘, user=‘YUANWEI‘, password=‘13974162858x‘, database=‘Baihe‘,charset=‘utf8‘)
 25     cur = conn.cursor() # 游标
 26     sql = """insert into users values({},‘{}‘,{},‘{}‘,‘{}‘,‘{}‘,{},‘{}‘,‘{}‘,‘{}‘,‘{}‘);"""  27         .format(personal[‘userID‘], personal[‘nickname‘], personal[‘age‘], ‘男‘ if personal[‘gender‘] == "1" else ‘女‘,
 28                 personal[‘cityChn‘], personal[‘educationChn‘], personal[‘height‘],
 29                 ‘没房‘ if personal[‘housing‘] == 0 else ‘有房‘, ‘没车‘ if personal[‘car‘] == 0 else ‘有车‘,
 30                 personal[‘incomeChn‘],personal[‘marriageChn‘])
 31     print(‘sql: ‘, sql)
 32     try:
 33         cur.execute(sql) # 执行sql语句
 34         save_photo(personal, get_miss_photo_binary(personal[‘headPhotoUrl‘])) # 保存头像
 35         print(‘成功获取该用户‘,personal[‘userID‘])
 36     except pymssql.IntegrityError:
 37         print(‘该用户已存在 ‘,personal[‘userID‘])
 38     except SystemError as sy: # 向err.txt导入错误日志
 39         with open(‘err.txt‘,‘a‘,encoding=‘utf8‘) as file:
 40             file.write(personal[‘nickname‘] + ‘ ‘ + str(personal[‘userID‘]) + ‘ 错误信息:‘ + str(sy) + ‘\n‘) # 写
 41     conn.commit() # 提交
 42     time.sleep(1)
 43     cur.close()
 44     conn.close()
 45
 46 def personal_data(lists):
 47     """
 48     获取一组的详细信息,最多为8个
 49
 50     :param lists: 列表类型,封装着一组信息
 51     :return: 无
 52     """
 53     for personal_data_dict in lists: # 遍历一组信息
 54         baihe_db(personal_data_dict)
 55
 56 def get_miss_photo_binary(photo_url):
 57     """
 58     获取照片的二进制数据
 59
 60     :param photo_url: 个人头像的url
 61     :return: 二进制数据
 62     """
 63     binary = ‘‘
 64     try:
 65         # 向服务器发送get请求,下载图片的二进制数据
 66         binary = requests.get(photo_url, headers=HEADERS,proxies={"http": HTTP_IP_PROXIES_2}).content
 67     except requests.exceptions.MissingSchema as rem:
 68         print(rem)
 69     except requests.exceptions.ProxyError: # 代理网络连接慢或无网络
 70         time.sleep(5)
 71         # 递归调用get_miss_photo_binary()
 72         get_miss_photo_binary(photo_url)
 73     return binary
 74
 75 def save_photo(personal,binary):
 76     """
 77     以‘E:/Baihe/1/‘为文件目录路径 或 以‘E:/Baihe/0/‘为文件目录路径
 78     以 name + id + .jpg 或 以 id + .jpg 为文件名
 79     有可能无相片
 80
 81     :param personal: 字典类型,封装着个人具体信息
 82     :param binary: 二进制数据
 83     :return: 无
 84     """
 85     if binary != ‘‘:
 86         file_path = ‘E:/Baihe/1/‘ if personal[‘gender‘] == "1" else ‘E:/Baihe/0/‘ #
 87         if not os.path.exists(file_path): # 如果该路径不存在
 88             os.makedirs(file_path) # 创建该路径
 89         try:
 90             # 向file_path路径保存图片
 91             with open(file_path + personal[‘nickname‘] + str(personal[‘userID‘]) + ‘.jpg‘,‘wb‘) as file:
 92                 file.write(binary)
 93         except OSError:
 94             with open(file_path + str(personal[‘userID‘]) + ‘.jpg‘,‘wb‘) as file:
 95                 file.write(binary)
 96
 97
 98 def no_exact_division(miss_id_list):
 99     """
100    当包含用户id的列表长度不能被8整除且列表长度小于8时调用该方法
101
102     :param miss_id_list: 为列表类型,封装着用户id
103     :return: 无
104     """
105     miss_info_lists = ba.get_miss_info(miss_id_list)  # 获取列表的个人信息
106     personal_data(miss_info_lists) # 遍历一组的信息
107
108
109 class Baihe(object):
110
111     def __init__(self,account,password):
112         """
113         初始化
114         :param account: 账号
115         :param password: 密码
116         """
117         self.is_begin = True # 开始爬取数据
118         self.index = 0 # 控制self.info长度为8个
119         self.info = [] # 临时保存用户id
120         self.page = 29 # 页码
121         self.account = account # 账号
122         self.password = password # 密码
123         self.req = requests.session() # 会话,保证Cookie一致
124
125     def login(self):
126        """
127        登录
128
129        :return: 无
130        """
131        # 登录的url
132        url_login = ‘http://my.baihe.com/Getinterlogin/gotoLogin?event=3&spmp=4.20.87.225.1049&‘ 133                    ‘txtLoginEMail={}&txtLoginPwd={}‘.format(self.account,self.password)
134        login_dict = {}
135        try:
136            # 向服务器发送get请求
137            login_dict = self.req.get(url_login,headers=HEADERS,proxies={"http": HTTP_IP_PROXIES_1},timeout=500).json()
138        except requests.exceptions.ProxyError:  # 代理网络连接慢或无网络
139             time.sleep(5)
140             # 递归调用self.login()
141             self.login()
142        time.sleep(3)
143        print(‘login: ‘,login_dict)
144        self.req.keep_alive = False # 关闭会话多余的连接
145        if login_dict[‘data‘] == 1:
146            print(‘登录成功‘)
147        else:
148            print(‘登录失败, 30分钟以后自动登录。。。。。。。。‘)
149            time.sleep(1800)
150            # 递归调用self.login()
151            self.login()
152        print(‘login is cookie ‘, requests.utils.dict_from_cookiejar(self.req.cookies)) # 查看登录后的会话cookie
153
154     def filtrate_miss(self,pages):
155         """
156         根据条件筛选数据,不提供条件参数
157
158         :param pages: 页码。该网站只提供62页的数据
159         :return: 包含160个用户的id的列表
160         """
161         time.sleep(2)
162         # 获取用户id的url
163         url_miss = ‘http://search.baihe.com/Search/getUserID‘
164         # from表单数据
165         params_miss = {"minAge": 18, "maxAge": 85, "minHeight": 144, "maxHeight": 210, "education": ‘1-8‘,
166                        "income": ‘1-12‘, "city": -1, "hasPhoto": 1, "page": pages, "sorterField": 1}
167         miss_dict = {}
168         try:
169             # 发送post请求
170             miss_dict = self.req.post(url_miss,data=params_miss,headers=HEADERS,proxies={‘http‘:HTTP_IP_PROXIES_2}).json()
171         except requests.exceptions.ProxyError:  # 代理网络连接慢或无网络
172             time.sleep(5)
173             # 递归调用self.filtrate_miss()
174             self.filtrate_miss(pages)
175         time.sleep(2)
176         print(‘miss is cookies ‘, requests.utils.dict_from_cookiejar(self.req.cookies)) # 查看筛选后的会话cookie
177         print(‘miss dict: ‘,miss_dict)
178         print(len(miss_dict[‘data‘]),‘个‘)
179         return miss_dict[‘data‘]
180
181     def get_miss_info(self,infos):
182         """
183         获取用户详细信息
184
185         :param infos: 列表类型,封装着个人id,可能为一组(8),或小于8个
186         :return: 包含一组的详细信息
187         """
188         if len(infos) == FING_INDEX: # infos列表长度等于8时
189             url_info = ‘http://search.baihe.com/search/getUserList?userIDs={},{},{},{},{},{},{},{}‘190                 .format(infos[0],infos[1],infos[2],infos[3],infos[4],infos[5],infos[6],infos[7])
191         else: # infos列表长度小于8时
192             bracket = ‘‘ # 参数userIDs的值
193             for lens in range(len(infos)):
194                 bracket += (str(infos[lens]) + ‘,‘) # 构造该表示:"{},{},{},{},{},{},{},{},"
195             # 获取用户详细信息的url      bracket[:len(bracket)-1]: 分片,干掉最后一个“,”
196             url_info = ‘http://search.baihe.com/search/getUserList?userIDs=‘ + bracket[:len(bracket)-1]
197         miss_info = {}
198         try:
199             # 发送post请求
200             miss_info = self.req.post(url_info,headers=HEADERS,proxies={‘http‘:HTTP_IP_PROXIES_2}).json()
201         except requests.exceptions.ProxyError:  # 代理网络连接慢或无网络
202             time.sleep(5)
203             # 递归调用self.get_miss_info()
204             self.get_miss_info(infos)
205         time.sleep(2)
206         return miss_info[‘data‘]
207
208     def exact_division(self,miss_id_list):
209         """
210         当包含用户id的列表长度能被8整除或包含用户id的列表长度不能被8整除且包含用户id的列表长度大于8
211
212         :param miss_id_list: id信息列表(160)
213         :return: 无
214         """
215         for user_id in miss_id_list:
216             self.index += 1
217             self.info.append(user_id)
218             if ba.index == FING_INDEX:
219                 print(‘user id: ‘, self.info)
220                 miss_info_list = ba.get_miss_info(self.info) # 8
221                 if None != miss_info_list:
222                     # 使self.index,self.info为初值,以便8人一组
223                     self.index = 0
224                     self.info = []
225                     print(‘miss info list: ‘, miss_info_list)
226                     personal_data(miss_info_list) # 遍历一组(8)的信息
227                 else:
228                     print(‘miss info list is null‘)
229                     continue
230
231     def main(self):
232         """
233         具体实施
234
235         :return: 无
236         """
237         self.login() # 登录
238         while self.is_begin: # 开始
239             print(‘正在获取‘,self.page,‘页.......‘)
240             miss_id_list = self.filtrate_miss(self.page) # 获取用户id列表
241             if len(miss_id_list) != 0: # 列表有id
242                 num = len(miss_id_list) % FING_INDEX # 模运算
243                 if num == 0: # 被8整除
244                     self.exact_division(miss_id_list)
245                 else: # 没有被8整除 , 虽然该分支没有执行,但还是要加上。因为该网站总是提供160个id
246                     print(‘余数: ‘,num)
247                     if len(miss_id_list) > FING_INDEX: # id列表的长度大于8
248                         copy_miss_id_list = miss_id_list[:len(miss_id_list) - num] # 分片 取8个一组
249                         self.exact_division(copy_miss_id_list)
250                         no_exact_division(miss_id_list[len(miss_id_list) - num:]) # 余下的个人信息
251                     else:
252                         no_exact_division(miss_id_list) # 小于8个人的个人的信息
253             else:
254                 print(‘数据已爬完。。。。。‘)
255                 self.is_begin = False
256             self.page += 1
257             time.sleep(10)
258 # 运行
259 if __name__ == ‘__main__‘:
260     ba = Baihe(‘xxxxxxxxx‘, ‘xxxxxxxxx‘) # 账号 密码
261     ba.main()

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

原文地址:https://www.cnblogs.com/YuWeiXiF/p/8439552.html

时间: 2024-10-08 22:30:05

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

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

爬取百合网的数据链接:http://www.cnblogs.com/YuWeiXiF/p/8439552.html 总共爬了22779条数据.第一次接触matplotlib库,以下代码参考了matplotlib官方文档:https://matplotlib.org/users/index.html. 数据查询用到了两个方法:getSexNumber(@sex varchar(2),@income varchar(30)).gethousingNumber(@sex varchar(2),@hou

Python3爬取今日头条有关《人民的名义》文章

Python3爬取今日头条有关<人民的名义>文章 最近一直在看Python的基础语法知识,五一假期手痒痒想练练,正好<人民的名义>刚结束,于是决定扒一下头条上面的人名的名义文章,试试技术同时可以集中看一下大家的脑洞也是极好的. 首先,我们先打开头条的网页版,在右上角搜索框输入关键词,通过chrome调试工具,我们定位到头条的search栏调用的的API为: http://www.toutiao.com/search_content/?offset=0&format=json

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

最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了javascript网络访问,然后将服务器返回的数据插入网页,无法通过网址直接获取对应页的的页面数据. 通过chrome的开发者工具,我们可以看到点击下一页按钮背后发起的网页访问: 在点击下一页时,浏览器向地址发起了访问.我们分析一下这个地址的结构: http://data.eastmoney.co

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

第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让我们方便的操作HTML,就像是用jQ一样 开始前,记得 npm install cheerio 为了能够并发的进行爬取,用到了Promise对象 //接受一个url爬取整个网页,返回一个Promise对象 function getPageAsync(url){ return new Promise(

[PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索(二)

前情提要:最近使用PHP实现了简单的网盘搜索程序,并且关联了微信公众平台,名字是网盘小说.用户可以通过公众号输入关键字,公众号会返回相应的网盘下载地址.就是这么一个简单的功能,类似很多的网盘搜索类网站,我这个采集和搜索程序都是PHP实现的,全文和分词搜索部分使用到了开源软件xunsearch. 上一篇([PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索)中我重点介绍了怎样去获取一大批的百度网盘用户,这一篇介绍怎样获得指定网盘用户的分享列表.同样的原理,也是找到百度获取分享列表的接口,

Python爬取天气网历史天气数据

我的第一篇博客,哈哈哈,记录一下我的Python进阶之路! 今天写了一个简单的爬虫. 使用python的requests 和BeautifulSoup模块,Python 2.7.12可在命令行中直接使用pip进行模块安装.爬虫的核心是利用BeautifulSoup的select语句获取需要的信息. pip install requests pip install bs4 以武汉市2017年5~7月的历史为例爬取天气网中武汉市的历史天气数据. 7月对应的网址为http://lishi.tianqi

python3爬取网页

爬虫 python3爬取网页资源方式(1.最简单: import'http://www.baidu.com/'print2.通过request import'http://www.baidu.com'print1.import urllib.request 'wd''python''opt-webpage''on''ie''gbk'GET和POST请求的不同之处是POST请求通常有"副作用" 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)

爬取豆瓣网评论最多的书籍

相信很多人都有书荒的时候,想要找到一本合适的书籍确实不容易,所以这次利用刚学习到的知识爬取豆瓣网的各类书籍,传送门https://book.douban.com/tag/?view=cloud. 首先是这个程序的结构,html_downloader是html下载器,html_outputer是导出到Excel表,html_parser是解析页面,make_wordcloud是制作词云,spided_main是程序入口,url_manager是URL管理器 主要实现思路是先请求下载需要的html,

python3爬取女神图片,破解盗链问题

title: python3爬取女神图片,破解盗链问题 date: 2018-04-22 08:26:00 tags: [python3,美女,图片抓取,爬虫, 盗链] comments: true 前言 其实,抓取图片和抓取小说内容没有任何本质的区别,步骤都是一样的. 但是图片读取的时候,会遇到一个盗链问题.这个问题是花的解决时间最长的. 环境 语言: python3 操作系统: mac 10.12.16 自定义工具包:soup_tool 其依赖工具如下: from urllib import