IPIDEA丨如何使用海外代理IP采集百度经验?
2020-03-30
本篇文章介绍一下如何简单直接地使用Python获取百度经验的文章内容,在开始之前相信大家已经对python语法基础已经有所掌握,不过如果你刚刚才开始学习也没关系,不妨直接跟着我们的代码,体验一下网络数据爬取的乐趣。
概况
语言:Python
涉及的库:requests, lxml, pymysql
难点:页面结构解析以及理清爬取顺序逻辑
网页分析
磨刀不误砍柴工,爬取之前我们需要打开网站,对网站路由层级及数据所在页面结构有足够充分地了解,以避免盲目地获取错误内容。
打开百度经验首页,同时按下F12查看页面调试。
为了完整地获取尽量多的经验文章,我们首先要所有的分类,通过查看页面源码发现,文章分类这部分内容是以静态形式存在,那么获取这部分内容就比较容易了。
然后任意选择一个分类打开,分析第二层级页面的结构。这个页面已经展示了部分文章列表,我们只需要依次选择各个分类标签以及分页标签就能获取这个分类下所能获得的所有文章链接了。
而页面内几个标签和分页的链接参数构成也十分简单,我们需要做的就是保存遍历所有的页面链接,获取所有文章链接并保存。
这样保存所有获取的文章链接就可以访问每个文章页面获取文章内容了。
编写代码
按照以上分析的页面层级结构和获取逻辑,接下来我们来用Python一步步编写爬取代码。
引入我们将会用到的库
import requests
import pymysql
from lxml import etree
新建一个类并初始化一些参数
class Spider():
def __init__(self):
self.domain = "https://jingyan.baidu.com"
self.mysql = pymysql.connect(host="127.0.0.1", port=3306, user='root', password='xxxc', db='spiderdb')
self.header = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Host': 'search.qianlima.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36'
}
首先我们需要获取首页的文章所有分类:
def get_category(self):
"""
获取分类
:return:
"""
url = "https://jingyan.baidu.com/"
res = requests.get(url,headers=self.headers)
html = etree.HTML(res.text)
category = html.xpath('//*[@id="nav-wrap"]/ul/li[2]/div/ul/li')
category = {}
for element in category:
name = element.xpath('a/text()')[0]
href = element.xpath('a/@href')[0]
category[name] = self.domain + href
print(category)
return category
运行后我们获取了所有的分类并输出
{'美食/营养': 'https://jingyan.baidu.com/list/1', '游戏/数码': 'https://jingyan.baidu.com/list/10', '手工/爱好': 'https://jingyan.baidu.com/list/37', '生活/家居': 'https://jingyan.baidu.com/list/50', '健康/养生': 'https://jingyan.baidu.com/list/73', '运动/户外': 'https://jingyan.baidu.com/list/86', '职场/理财': 'https://jingyan.baidu.com/list/93', '情感/交际': 'https://jingyan.baidu.com/list/101', '母婴/教育': 'https://jingyan.baidu.com/list/108', '时尚/美容': 'https://jingyan.baidu.com/list/123'}
获取分类页面下的所有文章列表,记得每个分类都有三页哦。
def get_list(self):
"""
按页获取文章列表
:return:
"""
data = {}
for item in self.category:
for i in [0,18,36]:
url = self.category[item] + "?type=1&pn=".format(i)
res = requests.get(url,headers=self.headers)
html = etree.HTML(res.text)
alist = html.xpath('//*[@id="img-list"]/ul/li/a')
print(len(alist))
for li in alist:
data["category"] = item
data["link"] = li.xpath('@href')[0]
data["title"] = li.xpath('div[2]/p[1]/text()')[0]
data["useful"] = li.xpath('div[2]/p[2]/span[1]/text()')[0]
data["share"] = li.xpath('div[2]/p[2]/span[2]/text()')[0]
self.save_data(data)
print(data)
time.sleep(2)
此外我们还需要将获取到的内容保存到数据库中,因此需要编写数据库调用的处理代码
def save_data(self,doc):
""" 保存数据 """
try:
data = (doc['category'], doc['title'], doc['link'],doc['useful'],doc['share'])
sql = "INSERT INTO bdjingyan(category,title,link,useful,share) " \
"VALUES ('%s','%s','%s','%s','%s')" % (data)
cursor = self.mysql.cursor()
try:
self.mysql.ping(reconnect=True)
cursor.execute(sql)
cursor.close()
self.mysql.commit()
except Exception as e:
self.mysql.rollback()
print('保存数据失败:', e)
print(sql)
self.mysql.close()
except KeyError as e:
print('保存数据失败,缺少字段:', e)
这样我们就完成了所有代码的编写,并且经过了代码调试,但是在正式爬取之前使用代理,通过代理IP访问获取数据,已避免代码被允许访问公开数据,造成前功尽弃。
并且数据能够成功写入数据库中
声明:本文来自网络投稿,不代表IPIDEA立场,若存在侵权、安全合规问题,请及时联系IPIDEA进行删除。
上一篇:常见的免费的HTTP有哪些风险?