python爬虫总章【含源码】,,用Python开发爬
python爬虫总章【含源码】,,用Python开发爬
用Python开发爬虫是一件很轻松愉悦的事情,因为其相关库较多,而且使用方便,短短十几行代码就可以完成一个爬虫的开发;
但是,在应对具有反爬措施的网站,使用js动态加载的网站,App采集的时候就得动动脑子了;并且在开发分布式爬虫,高性能爬虫的时候更得用心设计。
Python开发爬虫常用的工具总结
reqeusts:Python HTTP网络请求库;pyquery: Python HTML DOM结构解析库,采用类似JQuery的语法;BeautifulSoup:python HTML以及XML结构解析;selenium:Python自动化测试框架,可以用于爬虫;phantomjs:无头浏览器,可以配合selenium获取js动态加载的内容;re:python内建正则表达式模块;fiddler:抓包工具,原理就是是一个代理服务器,可以抓取手机包;anyproxy:代理服务器,可以自己撰写rule截取request或者response,通常用于客户端采集;celery:Python分布式计算框架,可用于开发分布式爬虫;gevent:Python基于协程的网络库,可用于开发高性能爬虫grequests:异步requestsaiohttp:异步http client/server框架asyncio:python内建异步io,事件循环库uvloop:一个非常快速的事件循环库,配合asyncio效率极高concurrent:Python内建用于并发任务执行的扩展scrapy:python 爬虫框架;Splash:一个JavaScript渲染服务,相当于一个轻量级的浏览器,配合lua脚本通过他的http API 解析页面;Splinter:开源自动化Python web测试工具pyspider:Python爬虫系统网页抓取思路
数据是否可以直接从HTML中获取?数据直接嵌套在页面的HTML结构中;数据是否使用JS动态渲染到页面中的?数据嵌套在js代码中,然后采用js加载到页面或者采用ajax渲染;获取的页面使用是否需要认证?需要登录后页面才可以访问;数据是否直接可以通过API得到?有些数据是可以直接通过api获取到,省去解析HTML的麻烦,大多数API都是以JSON格式返回数据;来自客户端的数据如何采集?例如:微信APP和微信客户端如何应对反爬
不要太过分,控制爬虫的速率,别把人家整垮了,那就两败俱伤了;使用代理隐藏真实IP,并且实现反爬;让爬虫看起来像人类用户,选择性滴设置以下HTTP头部:Host:https://www.baidu.comConnection:keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36Referer:http://s.weibo.com/user/gamelife1314&Refer=indexAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8查看网站的cookie,在某些情况下,请求需要添加cookie用于通过服务端的一些校验;案例说明
静态页面解析(获取微信公众号文章)
1 import pyquery 2 import re 3 4 5 def weixin_article_html_parser(html): 6 """ 7 解析微信文章,返回包含文章主体的字典信息 8 :param html: 文章HTML源代码 9 :return:10 """11 12 pq = pyquery.PyQuery(html)13 14 article = {15 "weixin_id": pq.find("#js_profile_qrcode "16 ".profile_inner .profile_meta").eq(0).find("span").text().strip(),17 "weixin_name": pq.find("#js_profile_qrcode .profile_inner strong").text().strip(),18 "account_desc": pq.find("#js_profile_qrcode .profile_inner "19 ".profile_meta").eq(1).find("span").text().strip(),20 "article_title": pq.find("title").text().strip(),21 "article_content": pq("#js_content").remove(‘script‘).text().replace(r"\r\n", ""),22 "is_orig": 1 if pq("#copyright_logo").length > 0 else 0,23 "article_source_url": pq("#js_sg_bar .meta_primary").attr(‘href‘) if pq(24 "#js_sg_bar .meta_primary").length > 0 else ‘‘,25 26 }27 28 # 使用正则表达式匹配页面中js脚本中的内容29 match = {30 "msg_cdn_url": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章封面图31 "var ct": {"regexp": "(?<=\")\d{10}(?=\")", "value": ""}, # 匹配文章发布时间32 "publish_time": {"regexp": "(?<=\")\d{4}-\d{2}-\d{2}(?=\")", "value": ""}, # 匹配文章发布日期33 "msg_desc": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章简介34 "msg_link": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章链接35 "msg_source_url": {"regexp": "(?<=‘).*(?=‘)", "value": ""}, # 获取原文链接36 "var biz": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},37 "var idx": {"regexp": "(?<=\")\d{1}(?=\")", "value": ""},38 "var mid": {"regexp": "(?<=\")\d{10,}(?=\")", "value": ""},39 "var sn": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},40 }41 count = 042 for line in html.split("\n"):43 for item, value in match.items():44 if item in line:45 m = re.search(value["regexp"], line)46 if m is not None:47 count += 148 match[item]["value"] = m.group(0)49 break50 if count >= len(match):51 break52 53 article["article_short_desc"] = match["msg_desc"]["value"]54 article["article_pos"] = int(match["var idx"]["value"])55 article["article_post_time"] = int(match["var ct"]["value"])56 article["article_post_date"] = match["publish_time"]["value"]57 article["article_cover_img"] = match["msg_cdn_url"]["value"]58 article["article_source_url"] = match["msg_source_url"]["value"]59 article["article_url"] = "https://mp.weixin.qq.com/s?__biz={biz}&mid={mid}&idx={idx}&sn={sn}".format(60 biz=match["var biz"]["value"],61 mid=match["var mid"]["value"],62 idx=match["var idx"]["value"],63 sn=match["var sn"]["value"],64 )65 66 return article67 68 69 if __name__ == ‘__main__‘:70 71 from pprint import pprint72 import requests73 url = ("https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1"74 "&sn=39419542de39a821bb5d1570ac50a313&scene=0#wechat_redirect")75 pprint(weixin_article_html_parser(requests.get(url).text))76 77 # {‘account_desc‘: ‘夜听,让更多的家庭越来越幸福。‘,78 # ‘article_content‘: ‘文字:安梦 \xa0 \xa0 声音:刘筱 得到了什么?又失去了什么?‘,79 # ‘article_cover_img‘: ‘http://mmbiz.qpic.cn/mmbiz_jpg/4iaBNpgEXstYhQEnbiaD0AwbKhmCVWSeCPBQKgvnSSj9usO4q997wzoicNzl52K1sYSDHBicFGL7WdrmeS0K8niaiaaA/0?wx_fmt=jpeg‘,80 # ‘article_pos‘: 1,81 # ‘article_post_date‘: ‘2017-07-02‘,82 # ‘article_post_time‘: 1499002202,83 # ‘article_short_desc‘: ‘周日 来自刘筱的晚安问候。‘,84 # ‘article_source_url‘: ‘‘,85 # ‘article_title‘: ‘【夜听】走到这里‘,86 # ‘article_url‘: ‘https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1&sn=39419542de39a821bb5d1570ac50a313‘,87 # ‘is_orig‘: 0,88 # ‘weixin_id‘: ‘yetingfm‘,89 # ‘weixin_name‘: ‘夜听‘}
使用phantomjs解析js渲染的页面–微博搜索
有些页面采用复杂的js逻辑处理,包含各种Ajax请求,请求之间还包含一些加密操作,通过分析js逻辑重新渲染页面拿到
想要的数据可谓比登天还难,没有坚实的js基础,不熟悉各种js框架,搞明白这种页面就别想了;
采取类似浏览器的方式渲染页面,直接获取页面HTML方便多了。
例如:http://s.weibo.com/搜索出来的结果是使用js动态渲染的,直接获取HTML并不会得到搜索的结果,所以我们要运行
页面中的js,将页面渲染成功以后,再获取它的HTML进行解析;
使用Python模拟登陆获取cookie
有些网站比较蛋疼,通常需要登录之后才可以获取数据,下面展示一个简单的例子:用于登录网站吗,获取cookie,然后可以用于其他请求
但是,这里仅仅在没有验证码的情况下,如果要有短信验证,图片验证,邮箱验证那就要另行设计了;
目标网站:http://www.newrank.cn,日期:2017-07-03,如果网站结构更改,就需要修改代以下码了;
1 #!/usr/bin/env python3 2 # encoding: utf-8 3 import time 4 from urllib import parse 5 6 from selenium import webdriver 7 from selenium.common.exceptions import TimeoutException, WebDriverException 8 from selenium.webdriver.common.action_chains import ActionChains 9 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities10 from pyquery import PyQuery11 12 13 def weibo_user_search(url: str):14 """通过phantomjs获取搜索的页面html"""15 16 desired_capabilities = DesiredCapabilities.CHROME.copy()17 desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "18 "AppleWebKit/537.36 (KHTML, like Gecko) "19 "Chrome/59.0.3071.104 Safari/537.36")20 desired_capabilities["phantomjs.page.settings.loadImages"] = True21 # 自定义头部22 desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 123 desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"24 desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"25 26 driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs", # 设置phantomjs路径27 desired_capabilities=desired_capabilities,28 service_log_path="ghostdriver.log",)29 # 设置对象的超时时间30 driver.implicitly_wait(1)31 # 设置页面完全加载的超时时间,包括页面全部渲染,异步同步脚本都执行完成32 driver.set_page_load_timeout(60)33 # 设置异步脚本的超时时间34 driver.set_script_timeout(60)35 36 driver.maximize_window()37 try:38 driver.get(url=url)39 time.sleep(1)40 try:41 # 打开页面之后做一些操作42 company = driver.find_element_by_css_selector("p.company")43 ActionChains(driver).move_to_element(company)44 except WebDriverException:45 pass46 html = driver.page_source47 pq = PyQuery(html)48 person_lists = pq.find("div.list_person")49 if person_lists.length > 0:50 for index in range(person_lists.length):51 person_ele = person_lists.eq(index)52 print(person_ele.find(".person_name > a.W_texta").attr("title"))53 return html54 except (TimeoutException, Exception) as e:55 print(e)56 finally:57 driver.quit()58 59 if __name__ == ‘__main__‘:60 weibo_user_search(url="http://s.weibo.com/user/%s" % parse.quote("新闻"))61 # 央视新闻62 # 新浪新闻63 # 新闻64 # 新浪新闻客户端65 # 中国新闻周刊66 # 中国新闻网67 # 每日经济新闻68 # 澎湃新闻69 # 网易新闻客户端70 # 凤凰新闻客户端71 # 皇马新闻72 # 网络新闻联播73 # CCTV5体育新闻74 # 曼联新闻75 # 搜狐新闻客户端76 # 巴萨新闻77 # 新闻日日睇78 # 新垣结衣新闻社79 # 看看新闻KNEWS80 # 央视新闻评论
使用Python模拟登陆获取cookie
有些网站比较蛋疼,通常需要登录之后才可以获取数据,下面展示一个简单的例子:用于登录网站吗,获取cookie,然后可以用于其他请求
但是,这里仅仅在没有验证码的情况下,如果要有短信验证,图片验证,邮箱验证那就要另行设计了;
目标网站:http://www.newrank.cn,日期:2017-07-03,如果网站结构更改,就需要修改代以下码了;
1 #!/usr/bin/env python3 2 # encoding: utf-8 3 4 from time import sleep 5 from pprint import pprint 6 7 from selenium.common.exceptions import TimeoutException, WebDriverException 8 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 9 from selenium import webdriver10 11 12 def login_newrank():13 """登录新榜,获取他的cookie信息"""14 15 desired_capabilities = DesiredCapabilities.CHROME.copy()16 desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "17 "AppleWebKit/537.36 (KHTML, like Gecko) "18 "Chrome/59.0.3071.104 Safari/537.36")19 desired_capabilities["phantomjs.page.settings.loadImages"] = True20 21 # 自定义头部22 desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 123 desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"24 desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"25 26 # 填写自己的账户进行测试27 user = {28 "mobile": "user",29 "password": "password"30 }31 32 print("login account: %s" % user["mobile"])33 34 driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs",35 desired_capabilities=desired_capabilities,36 service_log_path="ghostdriver.log", )37 38 # 设置对象的超时时间39 driver.implicitly_wait(1)40 # 设置页面完全加载的超时时间,包括页面全部渲染,异步同步脚本都执行完成41 driver.set_page_load_timeout(60)42 # 设置异步脚本的超时时间43 driver.set_script_timeout(60)44 45 driver.maximize_window()46 47 try:48 driver.get(url="http://www.newrank.cn/public/login/login.html?back=http%3A//www.newrank.cn/")49 driver.find_element_by_css_selector(".login-normal-tap:nth-of-type(2)").click()50 sleep(0.2)51 driver.find_element_by_id("account_input").send_keys(user["mobile"])52 sleep(0.5)53 driver.find_element_by_id("password_input").send_keys(user["password"])54 sleep(0.5)55 driver.find_element_by_id("pwd_confirm").click()56 sleep(3)57 cookies = {user["name"]: user["value"] for user in driver.get_cookies()}58 pprint(cookies)59 60 except TimeoutException as exc:61 print(exc)62 except WebDriverException as exc:63 print(exc)64 finally:65 driver.quit()66 67 if __name__ == ‘__main__‘:68 login_newrank()69 # login account: 1539510059070 # {‘CNZZDATA1253878005‘: ‘1487200824-1499071649-%7C1499071649‘,71 # ‘Hm_lpvt_a19fd7224d30e3c8a6558dcb38c4beed‘: ‘1499074715‘,72 # ‘Hm_lvt_a19fd7224d30e3c8a6558dcb38c4beed‘: ‘1499074685,1499074713‘,73 # ‘UM_distinctid‘: ‘15d07d0d4dd82b-054b56417-9383666-c0000-15d07d0d4deace‘,74 # ‘name‘: ‘15395100590‘,75 # ‘rmbuser‘: ‘true‘,76 # ‘token‘: ‘A7437A03346B47A9F768730BAC81C514‘,77 # ‘useLoginAccount‘: ‘true‘}
在获取cookie之后就可以将获得的cookie添加到后续的请求中了,但是因为cookie是具有有效期的,因此需要定时更新;
可以通过设计一个cookie池来实现,动态定时登录一批账号,获取cookie之后存放在数据库中(redis,MySQL等等),
请求的时候从数据库中获取一条可用cookie,并且添加在请求中访问;
使用pyqt5爬个数据试试(PyQt 5.9.2)
import sysimport csvimport pyqueryfrom PyQt5.QtCore import QUrlfrom PyQt5.QtWidgets import QApplicationfrom PyQt5.QtWebEngineWidgets import QWebEngineViewclass Browser(QWebEngineView): def __init__(self): super(Browser, self).__init__() self.__results = [] self.loadFinished.connect(self.__result_available) @property def results(self): return self.__results def __result_available(self): self.page().toHtml(self.__parse_html) def __parse_html(self, html): pq = pyquery.PyQuery(html) for rows in [pq.find("#table_list tr"), pq.find("#more_list tr")]: for row in rows.items(): columns = row.find("td") d = { "avatar": columns.eq(1).find("img").attr("src"), "url": columns.eq(1).find("a").attr("href"), "name": columns.eq(1).find("a").attr("title"), "fans_number": columns.eq(2).text(), "view_num": columns.eq(3).text(), "comment_num": columns.eq(4).text(), "post_count": columns.eq(5).text(), "newrank_index": columns.eq(6).text(), } self.__results.append(d) with open("results.csv", "a+", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["name", "fans_number", "view_num", "comment_num", "post_count", "newrank_index", "url", "avatar"]) writer.writerows(self.results) def open(self, url: str): self.load(QUrl(url))if __name__ == ‘__main__‘: app = QApplication(sys.argv) browser = Browser() browser.open("https://www.newrank.cn/public/info/list.html?period=toutiao_day&type=data") browser.show() app.exec_()浏览器抓包fiddler手机抓包
887934385交流群分享资料,分享技术
python爬虫总章【含源码】
相关内容
- python k-means聚类,,""k-means聚
- 50行Python代码实现视频中物体颜色识别和跟踪,,前言本
- Win10(PowerShell)下Python命令行tab自动补全,,用Python,直接
- python10行代码,让你成功伪装逃过反爬虫程序,python简
- Python库整理,后库整理要求,库名称简介Chard
- python-爬虫,爬虫python,1.爬虫的定义: 向
- python案例——体脂率项目,python项目案例,通过一个人的
- Python 【爬虫】,Python爬虫,爬虫的工作原理首先,
- python3_module_sys,pythonmodule,__author__
- python3+requests:post请求四种传送正文方式(详解),p
评论关闭