编写过程中的问题及程序源码
1.编写过程中的注意点
1.1 requests 模块需要开代理
因为纽约时报是外网,需要代理进行访问,requests模块需要开代理并进行设置:
# 代理
proxies = {'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}
res = requests.get(url, params=params, proxies=proxies);
如果这里的代理设置出错或者没有设置,可能会出现proxies相关报错:
requests.exceptions.ProxyError: HTTPSConnectionPool(host='cn.nytimes.com', port=443): Max retries exceeded with url: /search/data?query=%E4%B8%80%E5%B8%A6%E4%B8%80%E8%B7%AF&lang=&dt=json&from=0&size=100 (Caused by ProxyError('Cannot connect to proxy.', OSError(0, 'Error')))
1.2 sys.argv的使用
准备实现的功能是通过查询词启动爬虫程序进行搜索,就需要可以从命令行中读入关键词,这里使用的是sys模块中的sys.argv:
import sys
def main():
query = sys.argv[1]
getAllArticlesPreInfo(query)
if __name__ == "__main__":
main()
这样通过 D:\PyCharm\WorkPlace\nytimes>python news_crawler.py 奥运会 启动程序的时候,奥运会作为关键词赋给query,这样就实现了关键词查询。
1.3 用到的工具函数
(1)printState.py:
'''
printError(_str):输出错误信息
printSuccess(_str):输出执行成功的提示信息
printInfo(_str):输出普通信息
printTip(_str):输出提示信息
'''
def printError(_str):
print("[Error:{}出现错误]".format(_str))
def printSuccess(_str):
print("[Success:{}成功]".format(_str))
def printInfo(_str):
print("[Info:{}]".format(_str))
def printTip(_str):
print("[Iip:{}]".format(_str))
if __name__ == "__main__":
filename = "test.txt"
printInfo('写入文件' + filename)
printTip('写入文件' + filename)
2.完整项目代码:
nytimes项目目录下共2个文件:
2.1 news_crawler.py
# -*- coding:utf-8 -*-
# 获得查询的关键值返回的所有文章的信息
import requests
import json
from printState import *
import pymysql
import sys
def getAllArticlesPreInfo(query):
# url
url = 'https://cn.nytimes.com/search/data'
# 参数
params = {
"query": query,
"lang": "",
"dt": "json",
"from": 0,
"size": 100,
}
print("query = ", query)
# 代理
proxies = {'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}
res = requests.get(url, params=params, proxies=proxies)
total = json.loads(res.text)["total"]
# print(total)
total = 1001
_from = 0
_size = 100
# 连接mysql数据库
db = pymysql.connect(host='localhost', user='root', password='******', db='nytimes', port=3306)
# 使用cursor()方法获取操作游标
cursor = db.cursor()
print("数据库连接成功")
# 开始数据抓取
printTip("开始抓取相关文章")
while (True):
res = requests.get(url, params=params, proxies=proxies);
_from = _from + _size
params["from"] = _from;
data = res.text;
data = json.loads(data, encoding="utf8");
for i in range(100):
print(data['items'][i])
print(data['items'][i].get('id'))
# 分析数据
id = data['items'][i].get('id')
type = data['items'][i].get('type')
score = data['items'][i].get('score')
headline = data['items'][i].get('headline')
date = data['items'][i].get('publication_date')
web_url = data['items'][i].get('web_url')
description = data['items'][i].get('description')
# 将数据保存在数据库中
try:
# SQL 插入语句
sql = "INSERT INTO news(id, type, score, headline, date, url, description)VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s')" % (
id, type, score, headline, date, web_url, description)
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
if (_from > total):
break;
printSuccess("抓取到"+str(_from)+"个新闻");
printSuccess("抓取全部"+str(total)+"个新闻")
# 关闭数据库连接
db.close()
return data
def main():
query = sys.argv[1]
getAllArticlesPreInfo(query)
if __name__ == "__main__":
main()
2.2 printState.py
# -*- coding:utf-8 -*-
# 封装输出格式化
'''
printError(_str):输出错误信息
printSuccess(_str):输出执行成功的提示信息
printInfo(_str):输出普通信息
printTip(_str):输出提示信息
'''
def printError(_str):
print("[Error:{}出现错误]".format(_str))
def printSuccess(_str):
print("[Success:{}成功]".format(_str))
def printInfo(_str):
print("[Info:{}]".format(_str))
def printTip(_str):
print("[Iip:{}]".format(_str))
if __name__ == "__main__":
filename = "test.txt"
printInfo('写入文件' + filename)
printTip('写入文件' + filename)