rss feed相关知识
-
Android 开发技术周报 Issue#297新闻 谷歌新的Play Store实验功能可对同类应用进行正面比较 Android 11出Bug:顶栏遮挡游戏界面 不能全屏显示 开源库 lu 又一款virtual Dom Android渲染引擎 KtRssReader a Kotlin library for parsing RSS feed on Android. BlurHashExt Kotlin extensions of BlurHash for ImageView, Glide, Coil, Piccasso, and fast loading BlurHashDrawable optimized for Android. DependencyProperty DependencyProperty is a dependency resolution libra
-
ASP.NET的SEO:目录ASP.NET的SEO:基础知识ASP.NET的SEO:Global.asax和HttpModule中的RewritePath()方法——友好的URLASP.NET的SEO:正则表达式ASP.NET的SEO:服务器控件背后——SEO友好的Html和JavaScript ASP.NET的SEO:使用.ashx文件——排除重复内容 ASP.NET的SEO:HTTP报头状态码---内容重定向ASP.NET的SEO:Linq to XML---网站地图和RSS Feed ASP.NET的SEO:SEO Hack--- Html注入和Nofollow 这个系列可以算是我的一个读书笔记---WROX红皮书系列之《搜索引擎优化高级编程》(Professional Search Engine Optimization with ASP.NET:A Developer's Guide to SEO)。我觉得蛮不错的,第一是比较系统和权威;第二是不同于一般的SEO的理论介绍,它着
-
jQuery EasyUI 教程jQuery EasyUI 教程jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面插件。jQuery EasyUI 框架提供了创建网页所需的一切,帮助您轻松建立站点。本教程将告诉您如何使用 jQuery EasyUI 框架创建应用。现在开始学习 jQuery EasyUI!离线版教程CHM文档下载地址:http://url.cn/JBFcTA内容列表Application(应用)jQuery EasyUI 应用 - 创建 CRUD 应用jQuery EasyUI 应用 - 创建 CRUD 数据网格jQuery EasyUI 应用 - 创建展开行明细编辑表单的 CRUD 应用jQuery EasyUI 应用 - 创建 RSS Feed 阅读器Drag 与 Drop(拖动与放置,即拖放)jQuery EasyUI 拖放 - 基本的拖动和放置jQuery EasyUI 拖放 - 创建拖放的购物车jQuery EasyUI 拖放 - 创建学校课程表Menu 与 Button(菜单与按钮
-
php生成rss订阅//$news为重数据库里取出的数组$host = $_SERVER['HTTP_HOST'];$xmls = '<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel>';foreach
rss feed相关课程
-
Java眼中的XML 文件写入 XML 在数据传输及存储等方面非常流行,所以使用 JAVA 程序来生成相应用途的 XML 文件就变得非常重要,那么问题来了:如何使用 JAVA 程序生成一个 XML 文档呢?本节课将详细为你解答!
讲师:JessicaJiang 初级 55734人正在学习
rss feed相关教程
- 3. 真实案例分享 百度搜索(部分)<ul> <li> <a> <img src="https://pics0.baidu.com/feed/bd3eb13533fa828b324d63ea7f258e32970a5a0a.jpeg"> </a> </li> <li> <a> <img src="https://pics4.baidu.com/feed/30adcbef76094b36eaacf1e422f6b3df8d109dba.jpeg"> </a> </li> <li> <a> <img src="https://pics5.baidu.com/feed/730e0cf3d7ca7bcb8af180f33f33a465f724a821.jpeg"> </a> </li> </ul>淘宝网(部分)<div> <img src="//img.alicdn.com/imgextra/i3/180185321/O1CN01agBO561pB43nm30sJ_!!180185321-0-beehive-scenes.jpg_180x180xzq90.jpg_.webp"></div><div> <h4>Huawei/华为 p40 pro</h4> <p>MUI 10.1系统,内置华为AI语音助手Celia ,支持“Hey Celia”语音唤醒。HMS服务,华为P40搭载华为HMS服务。</p> <p><span></span>0 人说好</p></div>
- 1. 今日头条热点新闻数据抓取分析 今天的爬取对象是今日头条的热点新闻,下面的视频演示了如何找到头条新闻网站在获取热点新闻的 HTTP 请求:81从视频中我们可以看到头条新闻获取网站的接口示例如下:https://www.toutiao.com/api/pc/feed/?category=news_hot&utm_source=toutiao&widen=1&max_behot_time=1597152177&max_behot_time_tmp=1597152177&tadrequire=true&as=A1955F33D209BD8&cp=5F32293B3DE80E1&_signature=_02B4Z6wo0090109cl1gAAIBCcqbHy0H-dDdPWZPAAIzuFTZSh6NBsUuEpf13PktqrmxS-ZD4dEDZ6Ezcpyjo31hg62slsekkigwdRlS0FHfPsOvx.KRyeJBdEf5QI8nLcwEMyziL1YdPK6VD8f像这样的 http 请求时比较难模拟的,我们需要知道请求中所有参数的获取规则,特别是一些进行加密的方式,需要从前端中找出来并手工实现。比如这里的 URL,前几个参数都是固定值,其中 as、cp 和 _signature 则非常难获取,需要有极强的前端功底,网上也有大神对这些值的生成进行了分析和解密,当然这些不是我们学习的重点。最后一个问题:一次请求得到10条左右的新闻数据,那么像实现视频中那样更新更多新闻的请求,该如何完成呢?仔细分析下连续的刷新请求,我们会发现上述的 URL 请求结果中有这样一个参数:max_behot_time。第一次请求max_behot_time值为0next中的max_behot_time等于最后一条数据的behot_time值关于这个参数,我们得到两条信息:第一次请求热点新闻数据时,该参数为0;接下来的每次请求,带上的 max_behot_time 值为上一次请求热点新闻数据结果中的 next 字段中的 max_behot_time 键对应的值。它表示的是一个时间戳,其实就是意味着请求的热点新闻数据需要在这个时间之后;有了这样的信息,我们来基于 requests 库,纯手工实现一把头条热点新闻数据的抓取。我们按照如下的步骤来完成爬虫代码:准备基本变量,包括请求的基本 URL、请求参数、请求头等;hotnews_url = "https://www.toutiao.com/api/pc/feed/?"params = { 'category': 'news_hot', 'utm_source': 'toutiao', 'widen': 1, 'max_behot_time': '', 'max_behot_time_tmp': '',}headers = { 'referer': 'https://www.toutiao.com/ch/news_hot/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'}cookies = {'tt_webid':'6856365980324382215'} max_behot_time = '0'注意:上面的 cookies 中的 tt_webid 字段值可以通过右键看到,不过用处不大。tt_webid值的获取准备三个个方法:get_request_data() 、get_as_cp() 和 save_to_json()。其中第二个函数是网上有人对头条的 js 生成 as 和 cp 参数的代码进行了翻译,目前看来似乎还能使用;def get_request_data(url, headers): response = requests.get(url=url, headers=headers) return json.loads(response.text)def get_as_cp(): # 该函数主要是为了获取as和cp参数,程序参考今日头条中的加密js文件:home_4abea46.js zz = {} now = round(time.time()) e = hex(int(now)).upper()[2:] a = hashlib.md5() a.update(str(int(now)).encode('utf-8')) i = a.hexdigest().upper() if len(e) != 8: zz = {'as':'479BB4B7254C150', 'cp':'7E0AC8874BB0985'} return zz n = i[:5] a = i[-5:] r = '' s = '' for i in range(5): s = s + n[i] + e[i] for j in range(5): r = r + e[j + 3] + a[j] zz ={ 'as': 'A1' + s + e[-3:], 'cp': e[0:3] + r + 'E1' } return zzdef save_to_json(datas, file_path, key_list): """ 保存 json 数据 """ print('写入数据到文件{}中,共计{}条新闻数据!'.format(file_path, len(datas))) with codecs.open(file_path, 'a+', 'utf-8') as f: for d in datas: cleaned_data = {} for key in key_list: if key in d: cleaned_data[key] = d[key] print(json.dumps(cleaned_data, ensure_ascii=False)) f.write("{}\n".format(json.dumps(cleaned_data, ensure_ascii=False)))最后一步就是实现模拟刷新请求数据。下一次的请求会使用上一次请求结果中的 max_behot_time 值,这样能连续获取热点新闻数据,模拟头条页面向下的刷新过程;# 模拟向下下刷新5次获取新闻数据refresh_count = 5for _ in range(refresh_count): new_params = copy.deepcopy(params) zz = get_as_cp() new_params['as'] = zz['as'] new_params['cp'] = zz['cp'] new_params['max_behot_time'] = max_behot_time new_params['max_behot_time_tmp'] = max_behot_time request_url = "{}{}".format(hotnews_url, urlencode(new_params)) print(f'本次请求max_behot_time = {max_behot_time}') datas = get_request_data(request_url, headers=headers, cookies=cookies) max_behot_time = datas['next']['max_behot_time'] save_to_json(datas['data'], "result.json", key_list) time.sleep(2)最后来看看完整抓取热点新闻数据的代码运行过程,如下:82
- 3.3 内存异常 内存不足可能会导致系统发生颠簸,这是因为虽然内存不足时系统会终止某些进程来释放内存,但又会继续启动其他进程。要查看内存不足的确凿证据,请检查二进制事件日志中 am_proc_died 和 am_proc_start 条目的密集程度。内存不足还可能会减慢任务切换速度,并且可能会阻止进行返回尝试(因为用户尝试返回到的任务已被终止)。如果启动器被终止,它会在用户触摸主屏幕按钮时重启,并且日志中会显示启动器重新加载其内容。查看历史指标二进制事件日志中的 am_low_memory 条目表示最后一个缓存的进程已终止。在此之后,系统开始终止各项服务。日志范例如下:grep "am_low_memory" bugreport-2015-10-01-18-13-48.txt10-01 18:11:02.219 4600 7513 I am_low_memory: 4110-01 18:12:18.526 4600 14112 I am_low_memory: 3910-01 18:12:18.874 4600 7514 I am_low_memory: 3810-01 18:12:22.570 4600 14112 I am_low_memory: 4010-01 18:12:34.811 4600 20319 I am_low_memory: 4310-01 18:12:37.945 4600 6521 I am_low_memory: 4310-01 18:12:47.804 4600 14110 I am_low_memory: 43查看系统颠簸指标关于系统颠簸(分页、直接回收等)的其他指标包括 kswapd、kworker 和 mmcqd 消耗的 CPU 周期。日志范例如下:CPU INFO (top -n 1 -d 1 -m 30 -t)User 15%, System 54%, IOW 28%, IRQ 0%User 82 + Nice 2 + Sys 287 + Idle 1 + IOW 152 + IRQ 0 + SIRQ 5 = 529 PID TID PR CPU% S VSS RSS PCY UID Thread Proc15229 15229 0 19% R 0K 0K fg root kworker/0:229512 29517 1 7% D 1173524K 101188K bg u0_a27 Signal Catcher com.google.android.talk24565 24570 3 6% D 2090920K 145168K fg u0_a22 Signal Catcher com.google.android.googlequicksearchbox:search19525 19525 2 6% R 3476K 1644K fg shell top top24957 24962 2 5% R 1706928K 125716K bg u0_a47 Signal Catcher com.google.android.GoogleCamera19519 19519 3 4% S 0K 0K fg root kworker/3:1 120 120 0 3% S 0K 0K fg root mmcqd/118233 18233 1 3% S 0K 0K fg root kworker/1:125589 25594 1 2% D 1270476K 75776K fg u0_a8 Signal Catcher com.google.android.gms19399 19399 2 1% S 0K 0K fg root kworker/2:2 1963 1978 1 0% S 1819100K 125136K fg system android.fg system_server 1963 1981 3 0% S 1819100K 125136K fg system android.display system_server获取内存快照内存快照是一种 dumpstate,其中会列出正在运行的 Java 进程和本机进程.日志范例如下:Total PSS by OOM adjustment: 86752 kB: Native 22645 kB: surfaceflinger (pid 197) 18597 kB: mediaserver (pid 204) 136959 kB: System 136959 kB: system (pid 785) 220218 kB: Persistent 138859 kB: com.android.systemui (pid 947 / activities) 39178 kB: com.android.nfc (pid 1636) 28313 kB: com.android.phone (pid 1659) 13868 kB: com.redbend.vdmc (pid 1646) 9534 kB: Persistent Service 9534 kB: com.android.bluetooth (pid 23807) 178604 kB: Foreground 168620 kB: com.google.android.googlequicksearchbox (pid 1675 / activities) 9984 kB: com.google.android.apps.maps (pid 13952) 188286 kB: Visible 85326 kB: com.google.android.wearable.app (pid 1535) 38978 kB: com.google.process.gapps (pid 1510) 31936 kB: com.google.android.gms.persistent (pid 2072) 27950 kB: com.google.android.gms.wearable (pid 1601) 4096 kB: com.google.android.googlequicksearchbox:interactor (pid 1550) 52948 kB: Perceptible 52948 kB: com.google.android.inputmethod.latin (pid 1566) 150851 kB: A Services 81121 kB: com.google.android.gms (pid 1814) 37586 kB: com.google.android.talk (pid 9584) 10949 kB: com.google.android.music:main (pid 4019) 10727 kB: com.motorola.targetnotif (pid 31071) 10468 kB: com.google.android.GoogleCamera (pid 9984) 33298 kB: Previous 33298 kB: com.android.settings (pid 9673 / activities) 165188 kB: B Services 49490 kB: com.facebook.katana (pid 15035) 22483 kB: com.whatsapp (pid 28694) 21308 kB: com.iPass.OpenMobile (pid 5325) 19788 kB: com.google.android.apps.googlevoice (pid 23934) 17399 kB: com.google.android.googlequicksearchbox:search (pid 30359) 9073 kB: com.google.android.apps.youtube.unplugged (pid 21194) 7660 kB: com.iPass.OpenMobile:remote (pid 23754) 7291 kB: com.pujie.wristwear.pujieblack (pid 24240) 7157 kB: com.instagram.android:mqtt (pid 9530) 3539 kB: com.qualcomm.qcrilmsgtunnel (pid 16186) 204324 kB: Cached 43424 kB: com.amazon.mShop.android (pid 13558) 22563 kB: com.google.android.apps.magazines (pid 13844) 4298 kB: com.google.android.apps.enterprise.dmagent (pid 13826)
- 1. Windows 系统上的安装 友情提示:以下内容为安装步骤演示与补充说明,帮助加深理解。如果只想学习快速安装的话,记住一句话:一路 Next 就可以。忽略以下内容直接从 1.13 开始看吧。1.1 首先从 Git 官网直接下载安装程序。打开官网可以看到 Windows 版本的安装包下载位置,如红色箭头所示,点击即可开始下载最新版本安装包。安装包下载完成后,即可进行本地安装。接下来我将以 Git-2.15.1.2-64 版本来进行讲解。1.2 双击下载好的 .exe 文件,弹出如下安装界面,直接点击 “Next”。1.3 选择安装路径,点击右侧 “Browse” 按钮更改路径。建议大家单独创建一个目录,专门进行安装。我一般习惯固定使用一个非 C 盘来专门安装办公软件,每个软件单独使用一个文件夹,这样方便管理,尽量养成一个良好的习惯。1.4 选择好安装路径后,直接点击 “Next”,出现如下界面。这一步默认勾选了红色框内容,其他选项大家可以依据需要进行选择。我还多选择了 “Additional icons” 项目,表示会在桌面生成图标。倒数第二项表示:在所有控制台窗口中使用 TrueType 字体。最后一项表示:是否每天检查 Git 是否有 Windows 更新。1.5 选择完毕后,继续 “Next”,出现如下界面。这一步没有什么特别需要注意的,默认即可。然后同样点击 “Next”。1.6 接下来出现这个页面是选择 Git 使用的文本编辑器,默认即可。然后点击 “Next”。1.7 这一步是用来调整 Path 环境。第一种配置是 “仅从 Git Bash 使用 Git”。这是最安全的选择,因为您的 PATH 根本不会被修改,只能使用 Git Bash 的 Git 命令行工具。但是这将不能通过第三方软件使用。第二种配置是 “从命令行以及第三方软件进行 Git”。该选项也是安全的,因为它仅向 PATH 添加了一些最小的 Git 包装器,以避免使用可选的 Unix 工具造成环境混乱。能够从 Git Bash,命令提示符和 Windows PowerShell 以及在 PATH 中寻找 Git 的任何第三方软件中使用 Git。这也是推荐的选项。第三种配置是 “从命令提示符使用 Git 和可选的 Unix 工具”。警告:这将覆盖 Windows 工具,如 “ find 和 sort ”。只有在了解其含义后才使用此选项。使用推荐配置即可,点击 “Next” 按钮继续到下图的界面: 1.8 在这个界面选择 HTTP 传输。第一个选项是 “使用 OpenSSL 库”。服务器证书将使用 ca-bundle.crt 文件进行验证。第二个选项是 “使用本地 Windows 安全通道库”。服务器证书将使用 Windows 证书存储验证。此选项还允许您使用公司的内部根 CA 证书,例如通过 Active Directory Domain Services 。我使用默认选项,点击 “Next” 按钮继续到下图的界面: 1.9 继续来到这个界面,配置行尾符号转换。第一个选项是 “签出 Windows 风格,提交 Unix 风格的行尾”。签出文本文件时,Git 会将 LF 转换为 CRLF。提交文本文件时,CRLF 将转换为 LF。对于跨平台项目,这是 Windows 上的推荐设置(“ core.autocrlf” 设置为 “ true”)第二个选项是 “按原样签出,提交 Unix 样式的行尾”。签出文本文件时,Git 不会执行任何转换。 提交文本文件时,CRLF 将转换为 LF。对于跨平台项目,这是 Unix 上的建议设置(“ core.autocrlf” 设置为 “ input”)第三种选项是 “按原样签出,按原样提交”。当签出或提交文本文件时,Git 不会执行任何转换。不建议跨平台项目选择此选项(“ core.autocrlf” 设置为 “ false”)那么 CRLF 和 LF 有什么区别?CRLF 是 carriage return line feed 的缩写,中文意思是 回车换行。句尾使用回车换行两个字符 (即我们常在 Windows 编程时使用”\r\n” 换行)。LF 是 line feed 的缩写,中文意思是换行。我选择默认第一项,点击 “Next” 按钮继续到下一步: 1.10 配置终端模拟器和 Git Bash 一起使用第一个选项是 “使用 MinTTY(MSYS2 的默认终端)”。Git Bash 将使用 MinTTY 作为终端模拟器,该模拟器具有可调整大小的窗口,非矩形选择和 Unicode 字体。Windows 控制台程序(例如交互式 Python)必须通过 “ winpty” 启动才能在 MinTTY 中运行。第二个选项是 “使用 Windows 的默认控制台窗口”。Git 将使用 Windows 的默认控制台窗口(“cmd.exe”),该窗口可以与 Win32 控制台程序(如交互式 Python 或 node.js)一起使用,但默认的回滚非常有限,需要配置为使用 unicode 字体以正确显示非 ASCII 字符,并且在 Windows 10 之前,其窗口不能自由调整大小,并且只允许矩形文本选择。此处默认选了第一种选项,然后继续点击 “Next” 按钮进入下一步:1.11 配置额外选项第一个选项是 “启用文件系统缓存”。文件系统数据将被批量读取并缓存在内存中用于某些操作(“core.fscache” 设置为 “true”),性能显著提升。第二个选项是 “启用 Git 凭证管理器”。Windows 的 Git 凭证管理器为 Windows 提供安全的 Git 凭证存储,最显著的是对 Visual Studio Team Services 和 GitHub 的多因素身份验证支持。 (需要 .NET Framework v4.5.1 或更高版本)。第三个选项是 “启用符号链接”。启用符号链接(需要 SeCreateSymbolicLink 权限)。请注意,现有存储库不受此设置的影响。默认选了第一、第二选项,继续点击 “Next” 按钮进入下一步界面: 1.12 到这一步点击 Finish 按钮就完成安装了。等安装进度条满后,就可以在开始菜单里找到 “Git”->“Git Bash”,点击后出现一个类似命令行窗口的东西,就说明 Git 安装成功!此后,就可以在 Git Bash 窗口进行 windows 环境下的 Git 操作了!1.13 同样,我们不要忘记进行身份信息配置# git config --global user.name "Your Name"# git config --global user.email "Your Email"好了,windows 环境的安装步骤到这里已经结束了。大家可以看到其中并没有太多难点,基本上每一步按默认选项选择,一直点击 “Next” 往下走就可以完成基本的安装配置,绝对不会错。是不是很简单!接下来向大家介绍一些 Git 的基本命令,以便于在后续的学习中可以随时查看,同时也为我们之后的正式学习开一个头。请继续往下看:
- 2. 基于 Scrapy 框架的头条热点新闻数据爬取 还是按照我们以前的套路来进行,第一步是使用 startproject 命令创建热点新闻项目:[root@server ~]# cd scrapy-test/[root@server scrapy-test]# pyenv activate scrapy-testpyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.(scrapy-test) [root@server scrapy-test]# scrapy startproject toutiao_hotnewsNew Scrapy project 'toutiao_hotnews', using template directory '/root/.pyenv/versions/3.8.1/envs/scrapy-test/lib/python3.8/site-packages/scrapy/templates/project', created in: /root/scrapy-test/toutiao_hotnewsYou can start your first spider with: cd toutiao_hotnews scrapy genspider example example.com(scrapy-test) [root@server scrapy-test]#接着,根据我们要抓取的新闻数据字段,先定义好 Item:import scrapyclass ToutiaoHotnewsItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() abstract = scrapy.Field() source = scrapy.Field() source_url = scrapy.Field() comments_count = scrapy.Field() behot_time = scrapy.Field()有了 Item 之后,我们需要新建一个 Spider,可以使用 genspider 命令生成,也可以手工编写一个 Python 文件,代码内容如下:# 代码位置:toutiao_hotnews/toutiao_hotnews/spiders/hotnews.pyimport copyimport hashlibfrom urllib.parse import urlencodeimport jsonimport timefrom scrapy import Request, Spiderfrom toutiao_hotnews.items import ToutiaoHotnewsItemhotnews_url = "https://www.toutiao.com/api/pc/feed/?"params = { 'category': 'news_hot', 'utm_source': 'toutiao', 'widen': 1, 'max_behot_time': '', 'max_behot_time_tmp': '', 'as': '', 'cp': ''}headers = { 'referer': 'https://www.toutiao.com/ch/news_hot/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'}cookies = {'tt_webid':'6856365980324382215'} max_behot_time = '0'def get_as_cp(): # 该函数主要是为了获取as和cp参数,程序参考今日头条中的加密js文件:home_4abea46.js zz = {} now = round(time.time()) e = hex(int(now)).upper()[2:] a = hashlib.md5() a.update(str(int(now)).encode('utf-8')) i = a.hexdigest().upper() if len(e) != 8: zz = {'as':'479BB4B7254C150', 'cp':'7E0AC8874BB0985'} return zz n = i[:5] a = i[-5:] r = '' s = '' for i in range(5): s = s + n[i] + e[i] for j in range(5): r = r + e[j + 3] + a[j] zz ={ 'as': 'A1' + s + e[-3:], 'cp': e[0:3] + r + 'E1' } return zzclass HotnewsSpider(Spider): name = 'hotnews' allowed_domains = ['www.toutiao.com'] start_urls = ['http://www.toutiao.com/'] # 记录次数,注意停止 count = 0 def _get_url(self, max_behot_time): new_params = copy.deepcopy(params) zz = get_as_cp() new_params['as'] = zz['as'] new_params['cp'] = zz['cp'] new_params['max_behot_time'] = max_behot_time new_params['max_behot_time_tmp'] = max_behot_time return "{}{}".format(hotnews_url, urlencode(new_params)) def start_requests(self): """ 第一次爬取 """ request_url = self._get_url(max_behot_time) self.logger.info(f"we get the request url : {request_url}") yield Request(request_url, headers=headers, cookies=cookies, callback=self.parse) def parse(self, response): """ 根据得到的结果得到获取下一次请求的结果 """ self.count += 1 datas = json.loads(response.text) data = datas['data'] for d in data: item = ToutiaoHotnewsItem() item['title'] = d['title'] item['abstract'] = d.get('abstract', '') item['source'] = d['source'] item['source_url'] = d['source_url'] item['comments_count'] = d.get('comments_count', 0) item['behot_time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(d['behot_time'])) self.logger.info(f'得到的item={item}') yield item if self.count < self.settings['REFRESH_COUNT']: max_behot_time = datas['next']['max_behot_time'] self.logger.info("we get the next max_behot_time: {}, and the count is {}".format(max_behot_time, self.count)) yield Request(self._get_url(max_behot_time), headers=headers, cookies=cookies)这里的代码之前一样,第一次构造 Request 请求在 start_requests() 方法中,接下来在根据每次请求结果中获取 max_behot_time 值再进行下一次请求。另外我使用了全局计算变量 count 来模拟刷新的次数,控制请求热点新闻次数,防止无限请求下去。此外,Scrapy logger 在每个 spider 实例中提供了一个可以访问和使用的实例,我们再需要打印日志的地方直接使用 self.logger 即可,它对应日志的配置如下:# 代码位置:toutiao_hotnews/settings.py# 注意设置下下载延时DOWNLOAD_DELAY = 5# ...#是否启动日志记录,默认TrueLOG_ENABLED = True LOG_ENCODING = 'UTF-8'#日志输出文件,如果为NONE,就打印到控制台LOG_FILE = 'toutiao_hotnews.log'#日志级别,默认DEBUGLOG_LEVEL = 'INFO'# 日志日期格式 LOG_DATEFORMAT = "%Y-%m-%d %H:%M:%S"#日志标准输出,默认False,如果True所有标准输出都将写入日志中,比如代码中的print输出也会被写入到LOG_STDOUT = False接下来是 Item Pipelines 部分,这次我们将抓取到的新闻保存到 MySQL 数据库中。此外,我们还有一个需求就是选择当前最新的10条新闻发送到本人邮件,这样每天早上就能定时收到最新的头条新闻,岂不美哉。首先我想给自己的邮件发送 HTML 格式的数据,然后列出最新的10条新闻,因此第一步是是准备好模板热点新闻的模板页面,具体模板页面如下:# 代码位置: toutiao_hotnews/html_template.pyhotnews_template_html = """<!DOCTYPE html><html><head> <title>头条热点新闻一览</title></head><style type="text/css"></style><body><div class="container"><h3 style="margin-bottom: 10px">头条热点新闻一览</h3>$news_list</div></body></html>"""要注意一点,Scrapy 的邮箱功能只能发送文本内容,不能发送 HTML 内容。为了能支持发送 HTML 内容,我继承了原先的 MailSender 类,并对原先的 send() 方法稍做改动:# 代码位置: mail.pyimport logging from email import encoders as Encodersfrom email.mime.base import MIMEBasefrom email.mime.multipart import MIMEMultipartfrom email.mime.nonmultipart import MIMENonMultipartfrom email.mime.text import MIMETextfrom email.utils import COMMASPACE, formatdatefrom scrapy.mail import MailSenderfrom scrapy.utils.misc import arg_to_iterlogger = logging.getLogger(__name__)class HtmlMailSender(MailSender): def send(self, to, subject, body, cc=None, mimetype='text/plain', charset=None, _callback=None): from twisted.internet import reactor #####去掉了与attachs参数相关的判断语句,其余代码不变############# msg = MIMEText(body, 'html', 'utf-8') ########################################################## to = list(arg_to_iter(to)) cc = list(arg_to_iter(cc)) msg['From'] = self.mailfrom msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject rcpts = to[:] if cc: rcpts.extend(cc) msg['Cc'] = COMMASPACE.join(cc) if charset: msg.set_charset(charset) if _callback: _callback(to=to, subject=subject, body=body, cc=cc, attach=attachs, msg=msg) if self.debug: logger.debug('Debug mail sent OK: To=%(mailto)s Cc=%(mailcc)s ' 'Subject="%(mailsubject)s" Attachs=%(mailattachs)d', {'mailto': to, 'mailcc': cc, 'mailsubject': subject, 'mailattachs': len(attachs)}) return dfd = self._sendmail(rcpts, msg.as_string().encode(charset or 'utf-8')) dfd.addCallbacks( callback=self._sent_ok, errback=self._sent_failed, callbackArgs=[to, cc, subject, len(attachs)], errbackArgs=[to, cc, subject, len(attachs)], ) reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd) return dfd紧接着就是我们的 pipelines.py 文件中的代码:import loggingfrom string import Templatefrom itemadapter import ItemAdapterimport pymysqlfrom toutiao_hotnews.mail import HtmlMailSenderfrom toutiao_hotnews.items import ToutiaoHotnewsItemfrom toutiao_hotnews.html_template import hotnews_template_htmlfrom toutiao_hotnews import settingsclass ToutiaoHotnewsPipeline: logger = logging.getLogger('pipelines_log') def open_spider(self, spider): # 使用自己的MailSender类 self.mailer = HtmlMailSender().from_settings(spider.settings) # 初始化连接数据库 self.db = pymysql.connect( host=spider.settings.get('MYSQL_HOST', 'localhost'), user=spider.settings.get('MYSQL_USER', 'root'), password=spider.settings.get('MYSQL_PASS', '123456'), port=spider.settings.get('MYSQL_PORT', 3306), db=spider.settings.get('MYSQL_DB_NAME', 'mysql'), charset='utf8' ) self.cursor = self.db.cursor() def process_item(self, item, spider): # 插入sql语句 sql = "insert into toutiao_hotnews(title, abstract, source, source_url, comments_count, behot_time) values (%s, %s, %s, %s, %s, %s)" if item and isinstance(item, ToutiaoHotnewsItem): self.cursor.execute(sql, (item['title'], item['abstract'], item['source'], item['source_url'], item['comments_count'], item['behot_time'])) return item def query_data(self, sql): data = {} try: self.cursor.execute(sql) data = self.cursor.fetchall() except Exception as e: logging.error('database operate error:{}'.format(str(e))) self.db.rollback() return data def close_spider(self, spider): sql = "select title, source_url, behot_time from toutiao_hotnews where 1=1 order by behot_time limit 10" # 获取10条最新的热点新闻 data = self.query_data(sql) news_list = "" # 生成html文本主体 for i in range(len(data)): news_list += "<div><span>{}、<a href=https://www.toutiao.com{}>{} [{}]</a></span></div>".format(i + 1, data[i][1], data[i][0], data[i][2]) msg_content = Template(hotnews_template_html).substitute({"news_list": news_list}) self.db.commit() self.cursor.close() self.db.close() self.logger.info("最后统一发送邮件") # 必须加return,不然会报错 return self.mailer.send(to=["2894577759@qq.com"], subject="这是一个测试", body=msg_content, cc=["2894577759@qq.com"])这里我们会将 MySQL 的配置统一放到 settings.py 文件中,然后使用 spider.settings 来读取响应的信息。其中 open_spider() 方法用于初始化连接数据库,process_item() 方法用于生成 SQL 语句并提交插入动作,最后的 close_spider() 方法用于提交数据库执行动作、关闭数据库连接以及发送统一新闻热点邮件。下面是我们将这个 Pipeline 在 settings.py 中开启以及配置数据库信息、邮件服务器信息,同时也要注意关闭遵守 Robot 协议,这样爬虫才能正常执行。ROBOTSTXT_OBEY = False# 启动对应的pipelineITEM_PIPELINES = { 'toutiao_hotnews.pipelines.ToutiaoHotnewsPipeline': 300,}# 数据库配置MYSQL_HOST = "180.76.152.113"MYSQL_PORT = 9002MYSQL_USER = "store"MYSQL_PASS = "数据库密码"MYSQL_DB_NAME = "ceph_check"# 邮箱配置MAIL_HOST = 'smtp.qq.com'MAIL_PORT = 25MAIL_FROM = '2894577759@qq.com'MAIL_PASS = '你的授权码'MAIL_USER = '2894577759@qq.com'来看看我们这个头条新闻爬虫的爬取效果,视频演示如下:83
- ECharts 地图坐标系 掌握数据可视化,让数据更美观
rss feed相关搜索
-
radio
radiobutton
radiobuttonlist
radiogroup
radio选中
radius
rails
raise
rand
random_shuffle
randomflip
random函数
rangevalidator
rarlinux
ratio
razor
react
react native
react native android
react native 中文