任务目标:抓紧某贴吧的特定内容,以steam吧为例,我们抓取帖子名称-发布者-回复数并保存到tieba.db中。
注意点:1.url中关键字是URL编码形式的。
2.使用select方法定位class时,有些内容无非定位到。(具体原因我也不太清楚,可能是网站反爬虫措施导致的吧,如果有了解的,可以下方评论告知,万分感谢)
使用find_all方法可以精确定位到select方法无法定位到的数据。
代码如下:
数据库创建代码:
import sqlite3
import os
db_file = 'tieba.db'
def create_table():
# 1. 连接数据库
conn = sqlite3.connect(db_file)
# 2. 创建执行对象
cursor = conn.cursor()
# 3. 执行SQL语句
cursor.execute('''
create table movie(
id integer primary key autoincrement,
name text,
ren text,
num text
)
''')
# 4. 提交操作, 对于可以修改数据库内容的操作, 必须要提交
conn.commit()
# 5. 关闭连接
conn.close()
if __name__ == '__main__':
# 创建一个数据表
if not os.path.exists(db_file):
create_table()
爬虫代码:
from bs4 import BeautifulSoup
from urllib.request import urlopen
from urllib.parse import quote
import sqlite3
import os
import re
db_file = 'tieba.db'
def save(movie):
# 1. 连接
conn = sqlite3.connect(db_file)
# 2. 创建执行对象
cursor = conn.cursor()
# 3. 执行SQL语句
cursor.execute('''
insert into movie
(name, ren, num)
values
(?, ?, ?)
''', (movie.get('name'), movie.get('ren'), movie.get('num')) )
# 4. 提交
conn.commit()
# 5. 关闭
conn.close()
def get_one_page(key,x):
#字符串的格式化处理: {}占位符表示未知的参数,后面会补上
url = 'https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}'.format(quote(key), x * 50)
#第二种方法:url = 'https://maoyan.com/board/4?offset=%d'%(x*10)
response = urlopen(url)
return (response.read().decode())
def get_film(html):
ls = []
#html = get_one_page(x)
soup = BeautifulSoup(html,'html.parser')
#print(soup)
class_a = soup.select('a.j_th_tit ')
#print(class_a)
class_b = soup.select('.frs-author-name-wrap')
#print(class_b)
class_c = soup.find_all(title="回复")
#print(class_c)
#print(class_name,class_star,class_releasetime,class_integer,class_fraction)
for a,b,c in zip(class_a,class_b,class_c):
#print(a.get_text())
#print(b.get_text())
#print(c.get_text())
movie={}
movie['name']=a.get_text()
movie['ren'] = b.get_text()
movie['num'] = c.get_text()
ls.append(movie)
return ls
if __name__ == '__main__':
movie_list = []
html = get_one_page('steam',0)
movie_list = get_film(html)
# 使用数据库保存数据
print((movie_list))
# SQLite
for movie in movie_list:
save(movie)
和上次实例基本相似,主要就是URL构建时不同以及仅仅使用select方法已经无法满足需求,联系了find_all方法的使用。