def test_get_article_by_search(self): file_name = os.path.join(fake_data_path, 'search-gaokao-article.html') with io.open(file_name, encoding='utf-8') as f: search_gaokao_article = f.read() article_list = WechatSogouStructuring.get_article_by_search(search_gaokao_article) titles = [] abstracts = [] gzh_names = [] isvs = [] assert_equal(10, len(article_list)) for i in article_list: article = i['article'] titles.append(article['title']) abstracts.append(article['abstract']) assert_in('mp.weixin.qq.com/s?src=3×tamp=', article['url']) assert_true(isinstance(article['imgs'], list)) assert_greater_equal(len(article['imgs']), 1) gzh = i['gzh'] assert_in('mp.weixin.qq.com/profile?src=3×tamp', gzh['profile_url']) assert_in('wx.qlogo.cn/mmhead', gzh['headimage']) gzh_names.append(gzh['wechat_name']) isvs.append(gzh['isv']) # article assert_equal(['高考有多重要,为什么要重视高考?丨微观点', '高考:穷人考不好,中产考状元,精英不高考', '关于高考志愿的一点建议,仅供参考!', '刚刚,高考“满分”诞生了!(附各省高考分数线)', '高考学霸榜出炉!义乌最高分是她!排名...', '【高考】权威发布!2017年我省高考各项日程', '【高考】黑龙江省2017年普通高考成绩即将发布', '高考2017 | 全国各省区市高考录取时间大汇总,最新最全!', '高考志愿这么填,等于多考20分!这位特级教师的志愿填报方法很管用!', '高考填志愿,如何选专业?学长学姐有话说'], titles) assert_equal(['针对这个问题,其实占豪已经谈过,但还是想借高考之后、借这位小战友的留言,结合自己的人生经验,谈谈个人对这件事的看法....', '#条条大路通罗马,有人就出生在罗马#前几天北京文科高考状元熊轩昂接受澎湃新闻的采访的时候,说了下面这段话. “农村地区的...', '最近一直有哥迷留言问,填报高考志愿该选什么专业? 讲真,这个问题很难回答.专业选择没有绝对的好坏对错,跟考试成绩、个人兴...', '高考会有满分的情况吗?还真有!6月22日开始,全国各省的高考成绩陆续发布.22日晚上,成都市青白江区一个小区内人声鼎沸,因...', '浙江新高考各类别各段分数线及考生成绩于昨日揭晓.考生可凭考生号、密码查询自己的考试成绩!今年的高考成绩,经浙江省教育考...', '根据我省招生录取工作安排,现将近期有关高考工作日程公布如下:一、高考成绩公布时间6月24日左右省招考院通过黑龙江省招生考...', '黑龙江省2017年普通高考成绩即将发布 我省今年高考网上评卷工作现已结束,经过成绩核查、成绩校验等多个环节后,我省高考成绩...', '2017年高考录取工作开始了,各省区市高考录取工作何时进行?为了方便考生和家长及时了解,小编为大家作了最新最全的梳理.(图...', '各地高考成绩已陆续公布,在本公众号回复“高考查分”即可查询!~长按二维码即可关注本车~自昨天开始,全国各省份陆续公布...', '导语高考成绩和批次线已经出来了,想必同学们已经开始进入另一重要环节——志愿填报.你是不是在为选专业而纠结痛苦?不怕!...'], abstracts) # gzh assert_equal(['占豪', '才华有限青年', '新闻哥', '光明网', '义乌十八腔', '龙招港', '龙招港', '微言教育', '高考直通车', '阳光高考信息平台', ], gzh_names) assert_in(1, isvs) assert_in(0, isvs)
def search_article(self, keyword, page=1, timesn=WechatSogouConst.search_article_time.anytime, article_type=WechatSogouConst.search_article_type.all, ft=None, et=None, unlock_callback=None, identify_image_callback=None): """搜索 文章 对于出现验证码的情况,可以由使用者自己提供: 1、函数 unlock_callback ,这个函数 handle 出现验证码到解决的整个流程 2、也可以 只提供函数 identify_image_callback,这个函数输入验证码二进制数据,输出验证码文字,剩下的由 wechatsogou 包来解决 注意: 函数 unlock_callback 和 identify_image_callback 只需要提供一个,如果都提供了,那么 identify_image_callback 不起作用 Parameters ---------- keyword : str or unicode 搜索文字 page : int, optional 页数 the default is 1 timesn : WechatSogouConst.search_article_time 时间 anytime 没有限制 / day 一天 / week 一周 / month 一月 / year 一年 / specific 自定 the default is anytime article_type : WechatSogouConst.search_article_type 含有内容的类型 image 有图 / video 有视频 / rich 有图和视频 / all 啥都有 ft, et : datetime.date or None 当 tsn 是 specific 时,ft 代表开始时间,如: 2017-07-01 当 tsn 是 specific 时,et 代表结束时间,如: 2017-07-15 unlock_callback : callable 处理出现验证码页面的函数,参见 unlock_callback_example identify_image_callback : callable 处理验证码函数,输入验证码二进制数据,输出文字,参见 identify_image_callback_example Returns ------- list[dict] { 'article': { 'title': '', # 文章标题 'url': '', # 文章链接 'imgs': '', # 文章图片list 'abstract': '', # 文章摘要 'time': '' # 文章推送时间 }, 'gzh': { 'profile_url': '', # 公众号最近10条群发页链接 'headimage': '', # 头像 'wechat_name': '', # 名称 'isv': '', # 是否加v } } Raises ------ WechatSogouRequestsException requests error """ url = WechatSogouRequest.gen_search_article_url( keyword, page, timesn, article_type, ft, et) resp = self.__get_by_unlock( url, WechatSogouRequest.gen_search_article_url(keyword), is_need_unlock=lambda x: 'antispider' in x.url, unlock_platform=self.__unlock_sogou, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback) return WechatSogouStructuring.get_article_by_search(resp.text)
def search_article(self, keyword, page=1, timesn=WechatSogouConst.search_article_time.anytime, article_type=WechatSogouConst.search_article_type.all, ft=None, et=None, unlock_callback=None, identify_image_callback=None): """搜索 文章 对于出现验证码的情况,可以由使用者自己提供: 1、函数 unlock_callback ,这个函数 handle 出现验证码到解决的整个流程 2、也可以 只提供函数 identify_image_callback,这个函数输入验证码二进制数据,输出验证码文字,剩下的由 wechatsogou 包来解决 注意: 函数 unlock_callback 和 identify_image_callback 只需要提供一个,如果都提供了,那么 identify_image_callback 不起作用 Parameters ---------- keyword : str or unicode 搜索文字 page : int, optional 页数 the default is 1 timesn : WechatSogouConst.search_article_time 时间 anytime 没有限制 / day 一天 / week 一周 / month 一月 / year 一年 / specific 自定 the default is anytime article_type : WechatSogouConst.search_article_type 含有内容的类型 image 有图 / video 有视频 / rich 有图和视频 / all 啥都有 ft, et : datetime.date or None 当 tsn 是 specific 时,ft 代表开始时间,如: 2017-07-01 当 tsn 是 specific 时,et 代表结束时间,如: 2017-07-15 unlock_callback : callable 处理出现验证码页面的函数,参见 unlock_callback_example identify_image_callback : callable 处理验证码函数,输入验证码二进制数据,输出文字,参见 identify_image_callback_example Returns ------- list[dict] { 'article': { 'title': '', # 文章标题 'url': '', # 文章链接 'imgs': '', # 文章图片list 'abstract': '', # 文章摘要 'time': '' # 文章推送时间 }, 'gzh': { 'profile_url': '', # 公众号最近10条群发页链接 'headimage': '', # 头像 'wechat_name': '', # 名称 'isv': '', # 是否加v } } Raises ------ WechatSogouRequestsException requests error """ url = WechatSogouRequest.gen_search_article_url(keyword, page, timesn, article_type, ft, et) resp = self.__get_by_unlock(url, WechatSogouRequest.gen_search_article_url(keyword), is_need_unlock=lambda x: 'antispider' in x.url, unlock_platform=self.__unlock_sogou, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback) return WechatSogouStructuring.get_article_by_search(resp.text)
def test_get_article_by_search(self): file_name = os.path.join(fake_data_path, 'search-gaokao-article.html') with io.open(file_name, encoding='utf-8') as f: search_gaokao_article = f.read() article_list = WechatSogouStructuring.get_article_by_search( search_gaokao_article) titles = [] abstracts = [] gzh_names = [] isvs = [] assert_equal(10, len(article_list)) for i in article_list: article = i['article'] titles.append(article['title']) abstracts.append(article['abstract']) assert_in('mp.weixin.qq.com/s?src=3×tamp=', article['url']) assert_true(isinstance(article['imgs'], list)) assert_greater_equal(len(article['imgs']), 1) gzh = i['gzh'] assert_in('mp.weixin.qq.com/profile?src=3×tamp', gzh['profile_url']) assert_in('wx.qlogo.cn/mmhead', gzh['headimage']) gzh_names.append(gzh['wechat_name']) isvs.append(gzh['isv']) # article assert_equal([ '高考有多重要,为什么要重视高考?丨微观点', '高考:穷人考不好,中产考状元,精英不高考', '关于高考志愿的一点建议,仅供参考!', '刚刚,高考“满分”诞生了!(附各省高考分数线)', '高考学霸榜出炉!义乌最高分是她!排名...', '【高考】权威发布!2017年我省高考各项日程', '【高考】黑龙江省2017年普通高考成绩即将发布', '高考2017 | 全国各省区市高考录取时间大汇总,最新最全!', '高考志愿这么填,等于多考20分!这位特级教师的志愿填报方法很管用!', '高考填志愿,如何选专业?学长学姐有话说' ], titles) assert_equal([ '针对这个问题,其实占豪已经谈过,但还是想借高考之后、借这位小战友的留言,结合自己的人生经验,谈谈个人对这件事的看法....', '#条条大路通罗马,有人就出生在罗马#前几天北京文科高考状元熊轩昂接受澎湃新闻的采访的时候,说了下面这段话. “农村地区的...', '最近一直有哥迷留言问,填报高考志愿该选什么专业? 讲真,这个问题很难回答.专业选择没有绝对的好坏对错,跟考试成绩、个人兴...', '高考会有满分的情况吗?还真有!6月22日开始,全国各省的高考成绩陆续发布.22日晚上,成都市青白江区一个小区内人声鼎沸,因...', '浙江新高考各类别各段分数线及考生成绩于昨日揭晓.考生可凭考生号、密码查询自己的考试成绩!今年的高考成绩,经浙江省教育考...', '根据我省招生录取工作安排,现将近期有关高考工作日程公布如下:一、高考成绩公布时间6月24日左右省招考院通过黑龙江省招生考...', '黑龙江省2017年普通高考成绩即将发布 我省今年高考网上评卷工作现已结束,经过成绩核查、成绩校验等多个环节后,我省高考成绩...', '2017年高考录取工作开始了,各省区市高考录取工作何时进行?为了方便考生和家长及时了解,小编为大家作了最新最全的梳理.(图...', '各地高考成绩已陆续公布,在本公众号回复“高考查分”即可查询!~长按二维码即可关注本车~自昨天开始,全国各省份陆续公布...', '导语高考成绩和批次线已经出来了,想必同学们已经开始进入另一重要环节——志愿填报.你是不是在为选专业而纠结痛苦?不怕!...' ], abstracts) # gzh assert_equal([ '占豪', '才华有限青年', '新闻哥', '光明网', '义乌十八腔', '龙招港', '龙招港', '微言教育', '高考直通车', '阳光高考信息平台', ], gzh_names) assert_in(1, isvs) assert_in(0, isvs)
def search_article(self, keyword, page=1, timesn=WechatSogouConst.search_article_time.anytime, article_type=WechatSogouConst.search_article_type.all, ft=None, et=None, unlock_callback=None, identify_image_callback=None, decode_url=True): """搜索 文章 对于出现验证码的情况,可以由使用者自己提供: 1、函数 unlock_callback ,这个函数 handle 出现验证码到解决的整个流程 2、也可以 只提供函数 identify_image_callback,这个函数输入验证码二进制数据,输出验证码文字,剩下的由 wechatsogou 包来解决 注意: 函数 unlock_callback 和 identify_image_callback 只需要提供一个,如果都提供了,那么 identify_image_callback 不起作用 Parameters ---------- keyword : str or unicode 搜索文字 page : int, optional 页数 the default is 1 timesn : WechatSogouConst.search_article_time 时间 anytime 没有限制 / day 一天 / week 一周 / month 一月 / year 一年 / specific 自定 the default is anytime article_type : WechatSogouConst.search_article_type 含有内容的类型 image 有图 / video 有视频 / rich 有图和视频 / all 啥都有 ft, et : datetime.date or None 当 tsn 是 specific 时,ft 代表开始时间,如: 2017-07-01 当 tsn 是 specific 时,et 代表结束时间,如: 2017-07-15 unlock_callback : callable 处理出现验证码页面的函数,参见 unlock_callback_example identify_image_callback : callable 处理验证码函数,输入验证码二进制数据,输出文字,参见 identify_image_callback_example decode_url : bool 是否解析 url Returns ------- list[dict] { 'article': { 'title': '', # 文章标题 'url': '', # 文章链接 'imgs': '', # 文章图片list 'abstract': '', # 文章摘要 'time': '' # 文章推送时间 }, 'gzh': { 'profile_url': '', # 公众号最近10条群发页链接 'headimage': '', # 头像 'wechat_name': '', # 名称 'isv': '', # 是否加v } } Raises ------ WechatSogouRequestsException requests error """ def limit_sleep(): """ 根据limit_seconds参数延迟一段时间 """ seconds = self.limit_seconds if seconds: time.sleep(seconds) url = WechatSogouRequest.gen_search_article_url(keyword, page, timesn, article_type, ft, et) session = requests.session() try: resp = self.__get_by_unlock(url, WechatSogouRequest.gen_search_article_url(keyword), unlock_platform=self.__unlock_sogou, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback, session=session) article_list = WechatSogouStructuring.get_article_by_search(resp.text) limit_sleep() for i in article_list: if decode_url: i['article']['url'] = self.__format_url(i['article']['url'], url, resp.text, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback, session=session) limit_sleep() i['gzh']['profile_url'] = self.__format_url(i['gzh']['profile_url'], url, resp.text, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback, session=session) yield i except WechatSogouRequestsException as e: raise e
def get_target_list_v2(self, target): page = 10 keyword = target['jobTypeName'] target['items'] = [] target['main_url'] = [] first_data = 'init_proxy' for i in range(page): while True: url = u'http://weixin.sogou.com/weixin?type=2&page=%s&ie=utf8&query=%s&interation=' % ( i + 1, parse.quote(keyword)) self.headers['Referer'] = url self.headers['Cookie'] = 'SUV="";SNUID="";' if url not in self.saved_data_list: try: self.logger.debug("queue get before size:%s" % q_proxies.qsize()) proxies = q_proxies.get() self.logger.debug("queue get after size :%s" % q_proxies.qsize()) resp = requests.get( url, proxies=proxies, headers=self.headers, timeout=8, ) if resp.ok: if u'antispider' in resp.url: # TODO:记录一下被识别为爬虫的代理IP到数据库 # self.proxies_table.create( object=proxies['http'], ) self.logger.debug( u'Name: %s, Page: %s, DetachAntiSpider: %s' % (keyword, str(i + 1), proxies['http'])) first_data = 'detach_spider' continue else: time.sleep(random.randint(2, 5)) target_little_list = WechatSogouStructuring.get_article_by_search( resp.text) if target_little_list.__len__() == 0: break # break for the page doesnt have data target['items'].append(target_little_list) target['main_url'].append(url) self.logger.debug( 'get item %s page %d total %d ' % (keyword, i + 1, target_little_list.__len__())) break # break for success else: self.logger.debug( u'Name: %s, Page: %s, HttpError: %s' % (keyword, str(i + 1), str(resp.status_code))) first_data = 'http_error' except Exception as e: self.logger.debug(u'Name: %s, Page: %s, Error: %s' % (keyword, i + 1, type(e))) first_data = 'catch_exception' else: self.logger.debug('the url had been crawled') break # break for exist self.logger.debug(u'Name: %s, Total: %s' % (keyword, len(target['items']))) return target
def search_article(self, keyword, page=1, timesn=0, article_type=WechatSogouRequest.TYPE_ALL, ft=None, et=None, deblocking_callback=None, identify_image_callback=None): """搜索 文章 对于出现验证码的情况,可以由使用者自己提供: 1、函数 deblocking_callback ,这个函数 handle 出现验证码到解决的整个流程 2、也可以 只提供函数 identify_image_callback,这个函数输入验证码二进制数据,输出验证码文字,剩下的由 wechatsogou 包来解决 注意: 函数 deblocking_callback 和 identify_image_callback 只需要提供一个,如果都提供了,那么 identify_image_callback 不起作用 Parameters ---------- keyword : str or unicode 搜索文字 page : int, optional 页数 the default is 1 timesn : {0, 1, 2, 3, 4, 5} 时间 0 没有限制 / 1一天 / 2一周 / 3一月 / 4一年 / 5自定 the default is 0 article_type : {'image', 'video', 'rich', 'all'} 含有内容的类型 TYPE_IMAGE 有图 / TYPE_VIDEO 有视频 / TYPE_RICH 有图和视频 / TYPE_ALL 啥都有 ft, et : datetime.date or None 当 tsn 是 5 时,ft 代表开始时间,如: 2017-07-01 当 tsn 是 5 时,et 代表结束时间,如: 2017-07-15 deblocking_callback : callable 处理出现验证码页面的函数,参见 deblocking_callback_example identify_image_callback : callable 处理验证码函数,输入验证码二进制数据,输出文字,参见 identify_image_callback_example Returns ------- list[dict] { 'url': '', 'img': '', 'name': '', 'wechat_id': '', 'post_perm': '', 'qrcode': '', 'introduction': '', 'authentication': '' } Raises ------ WechatSogouRequestsException requests error """ req = requests.session() url = WechatSogouRequest.gen_search_article_url( keyword, page, timesn=timesn, article_type=article_type, ft=ft, et=et) url_referer = WechatSogouRequest.gen_search_article_url(keyword) resp = WechatSogouRequest.get( url, req=req, headers=self.__set_cookie(referer=url_referer)) if not resp.ok: raise WechatSogouRequestsException('WechatSogouAPI search_article', resp) if 'antispider' in resp.url: self.__deblocking_search(url, resp, req, deblocking_callback, identify_image_callback) resp = WechatSogouRequest.get( url, req=req, headers=self.__set_cookie(referer=url_referer)) # req=req return WechatSogouStructuring.get_article_by_search(resp.text)